http://poj.org/problem?id=1274
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 17672 | Accepted: 8060 |
Description
Input
Output
Sample Input
5 5 2 2 5 3 2 3 4 2 1 5 3 1 2 5 1 2
Sample Output
4题意:
一只牛对应一个房间,一个房间住一只牛
问最大的匹配数:
方法一:
最大流
#include"string.h" #include"stdio.h" #include"iostream" #include"queue" #define M 10009 #define inf 999999999 using namespace std; struct st { int u,v,w,next; }edge[M]; int t,head[M],use[M],pre[M],dis[M]; void init() { t=0; memset(head,-1,sizeof(head)); } void add(int u,int v,int w) { edge[t].u=u; edge[t].v=v; edge[t].w=w; edge[t].next=head[u]; head[u]=t++; edge[t].u=v; edge[t].v=u; edge[t].w=0; edge[t].next=head[v]; head[v]=t++; } int BFS(int S,int T) { int i; queue<int>q; memset(dis,-1,sizeof(dis)); dis[S]=0; q.push(S); while(!q.empty()) { int u=q.front(); q.pop(); for(i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(edge[i].w&&dis[v]==-1) { dis[v]=dis[u]+1; if(v==T) return 1; q.push(v); } } } return 0; } int DFS(int S,int a,int T) { if(S==T) return a; for(int i=head[S];i!=-1;i=edge[i].next) { int v=edge[i].v; if(edge[i].w&&dis[v]==dis[S]+1) { int tt=DFS(v,min(a,edge[i].w),T); if(tt) { edge[i].w-=tt; edge[i^1].w+=tt; return tt; } } } return 0; } int solve(int S,int T) { int ans=0; while(BFS(S,T)) { while(int tt=DFS(S,inf,T)) ans+=tt; } return ans; }
<pre name="code" class="cpp">/*int BFS(int S,int T) { queue<int>q; memset(pre,-1,sizeof(pre)); memset(dis,-1,sizeof(dis)); dis[S]=0; q.push(S); int i; while(!q.empty()) { int u=q.front(); q.pop(); for(i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(edge[i].w&&dis[v]==-1) { pre[v]=i; dis[v]=dis[u]+1; if(v==T) { return 1; } q.push(v); } } } return 0; } int solve(int S,int T) { int ans=0,i; while(BFS(S,T)) { int mini=inf; for(i=pre[T];i!=-1;i=pre[edge[i].u]) { mini=min(mini,edge[i].w); } for(i=pre[T];i!=-1;i=pre[edge[i].u]) { edge[i].w-=mini; edge[i^1].w+=mini; } ans+=mini; } return ans; }*/
int main() { int n,m,i,k; while(scanf("%d%d",&n,&m)!=-1) { init(); for(i=1;i<=n;i++) { scanf("%d",&k); while(k--) { int b; scanf("%d",&b); add(i,b+n,1); } } for(i=1;i<=n;i++) add(0,i,1); for(i=1;i<=m;i++) add(i+n,m+n+1,1); int ans=solve(0,m+n+1); printf("%d\n",ans); } return 0; }方法二:
二分图最大匹配
程序:
#include"string.h" #include"stdio.h" #include"iostream" #include"queue" #define M 10009 #define inf 999999999 using namespace std; struct st { int u,v,next; }edge[M]; int head[M],use[M],t,x[M],y[M]; void init() { t=0; memset(head,-1,sizeof(head)); } void add(int u,int v) { edge[t].u=u; edge[t].v=v; edge[t].next=head[u]; head[u]=t++; } int finde(int u) { for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(!use[v]) { use[v]=1; if(!y[v]||finde(y[v])) { use[v]=1; y[v]=u; x[u]=v; return 1; } } } return 0; } int main() { int n,m,i,k; while(scanf("%d%d",&n,&m)!=-1) { init(); for(i=1;i<=n;i++) { scanf("%d",&k); while(k--) { int b; scanf("%d",&b); add(i,b+n); } } int ans=0; memset(x,0,sizeof(x)); memset(y,0,sizeof(y)); for(i=1;i<=n;i++) { if(!x[i]) { memset(use,0,sizeof(use)); ans+=finde(i); } } printf("%d\n",ans); } return 0; }