poj 1274 The Perfect Stall

可以当成最大流,也可以当成最大二分匹配。。。

 

我现在还不会二分匹配。。。我是把它当成最大流做的。。

 

多汇点,多源点的最大流。

 

分别设一个源点汇点,即可。

 

将奶牛和stall编号编一起,奶牛和每个喜欢的stall的容量是1,源点和每个奶牛的容量是1,每个stall和汇点的容量是1,求最大流即可。

 

匈牙利算法见:http://blog.csdn.net/zxy_snow/archive/2011/02/25/6207817.aspx

 

#include <cstdio> #include <cstdlib> #include <iostream> #include <string.h> #include <queue> #include <limits.h> #define MAX 420 using namespace std; int n,m; int cap[MAX][MAX]; int EKarp(int s,int t) { queue<int> Q; int flow[MAX][MAX],pre[MAX],a[MAX]; int u,v,to,f = 0; memset(flow,0,sizeof(flow)); while(1) { memset(a,0,sizeof(a)); a[s] = INT_MAX; Q.push(s); while( !Q.empty() ) { u = Q.front(); Q.pop(); for(v=s; v<=t; v++) if( !a[v] && cap[u][v] > flow[u][v] ) { Q.push(v); pre[v] = u; a[v] = a[u] < cap[u][v] - flow[u][v] ? a[u] : cap[u][v] - flow[u][v]; } } if( a[t] == 0 ) break; for(u=t; u!=s; u=pre[u]) { flow[pre[u]][u] += a[t]; flow[u][pre[u]] -= a[t]; } f += a[t]; } return f; } int main() { int i,ans,to,num; while( scanf("%d%d",&n,&m) != EOF ) { memset(cap,0,sizeof(cap)); for(i=1; i<=n; i++) { scanf("%d",&num); while( num-- ) { scanf("%d",&to); cap[m+i][to] = 1; } } for(i=m+1; i<=m+n; i++) cap[0][i] = 1; for(i=1; i<=m; i++) cap[i][m+n+1] = 1; ans = EKarp(0,m+n+1); printf("%d/n",ans); } return 0; }  

你可能感兴趣的:(算法)