两题二分图匹配的题:
1.一个农民有n头牛和m个畜栏,对于每个畜栏,每头牛有不同喜好,有的想去,有的不想,对于给定的喜好表,你需要求出最大可以满足多少头牛的需求。
2.给你学生数和课程数,以及学生上的课,如果可以做到每个学生代表不同的课程并且所有的课程都被代表输出"YES“(学生能代表一门课当且仅当他上过)。
1.POJ 1274 The Perfect Stall
http://poj.org/problem?id=1274
和上一题过山车一样,也是二分图匹配的。
水题。
#include<cstdio> #include<cstring> const int MAXN=200+10; int head[MAXN],len,res[MAXN]; bool vis[MAXN]; struct edge { int to,next; }e[MAXN*MAXN]; void add(int from,int to) { e[len].to=to; e[len].next=head[from]; head[from]=len++; } bool find(int a) { for(int i=head[a];i!=-1;i=e[i].next) { int id=e[i].to; if(!vis[id]) { vis[id]=true; if(res[id]==0 || find(res[id])) { res[id]=a; return true; } } } return false; } int main() { int n,m; while(~scanf("%d%d",&n,&m)) { memset(head,-1,sizeof(head)); len=0; memset(res,0,sizeof(res)); for(int i=1;i<=n;i++) { int k,to; scanf("%d",&k); for(int j=0;j<k;j++) { scanf("%d",&to); add(i,to); } } int ans=0; for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); if(find(i)) ans++; } printf("%d\n",ans); } return 0; }
2.POJ 1469 COURSES(zoj 1140)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=140
http://poj.org/problem?id=1469
上面的代码改改就过了。。。
#include<cstdio> #include<cstring> const int MAXN=300+10; int head[MAXN],len,res[MAXN]; bool vis[MAXN]; struct edge { int to,next; }e[MAXN*MAXN]; void add(int from,int to) { e[len].to=to; e[len].next=head[from]; head[from]=len++; } bool find(int a) { for(int i=head[a];i!=-1;i=e[i].next) { int id=e[i].to; if(!vis[id]) { vis[id]=true; if(res[id]==0 || find(res[id])) { res[id]=a; return true; } } } return false; } int main() { int T; scanf("%d",&T); while(T--) { int p,n; scanf("%d%d",&p,&n); memset(head,-1,sizeof(head)); len=0; memset(res,0,sizeof(res)); for(int i=1;i<=p;i++) { int k,to; scanf("%d",&k); for(int j=0;j<k;j++) { scanf("%d",&to); add(i,to); } } int ans=0; for(int i=1;i<=p;i++) { memset(vis,0,sizeof(vis)); if(find(i)) ans++; } if(ans==p) puts("YES"); else puts("NO"); } return 0; }