洛谷[P2417 课程]

题目链接:

点我

题目分析:

二分图最大匹配裸题,跑完匈牙利判断\(ans\)是否等于教室数即可
多组数据请注意初始化。

代码:

#include<bits/stdc++.h>
#define N 20000*2
#define M 5000000*2
inline int read(){
    int cnt=0;int f=1;char c;
    c=getchar();
    while(!isdigit(c)){
        if(c=='-')f=-f;
        c=getchar();
    }
    while(isdigit(c)){
        cnt=cnt*10+c-'0';
        c=getchar();
    }
    return cnt*f;
}
int n,nxt[M],first[N],to[M],match[N],tot,ans,res,x,t,p,m;
bool vis[N];
void add(int x,int y){
    nxt[++tot]=first[x];
    first[x]=tot;
    to[tot]=y;
}
int find(int u){
    for(register int i=first[u];i;i=nxt[i]){
        int v=to[i];
        if(vis[v])continue;
        else {
            vis[v]=1;
            if(match[v]==-1||find(match[v])){
                match[v]=u;
                return 1;
            }
        }
    }
    return 0;
}
int hungary(){
    for(register int i=1;i<=p;i++) match[i]=-1;
    for(register int i=1;i<=n;i++){
        for(register int j=1;j<=p;j++) vis[j]=false;
        ans+=find(i);
    }
    return ans;
}
int main(){
    t=read();
    while(t--){
        p=read();n=read();
        for(register int i=1;i<=p;i++){
            m=read();
            for(register int j=1;j<=m;j++){
                x=read();add(x,i);
            }
        }
        res=hungary();
        if(res==p)printf("YES\n");
        else printf("NO\n");
        for(register int i=1;i<=n;i++)first[i]=match[i]=0;
        for(register int i=1;i<=tot;i++)nxt[i]=to[i]=0;
        tot=0;res=0;ans=0;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/kma093/p/10327266.html