@Asuna
2017-02-23T05:37:30.000000Z
字数 1613
阅读 962
题解
题意:求一个二分图的最大匹配。
题解:匈牙利算法求二分图最大匹配。
参考代码:
#include<iostream>#include<cstdio>#include<cstring>using namespace std;int g[510][510],mat[510],t,n,m;bool used[510];bool dfs(int u){for (int v=1; v<=g[0][1]; v++){if (g[u][v] && !used[v]){used[v]=true;if (mat[v]==-1 || dfs(mat[v])){mat[v]=u;return true;}}}return false;}int hungary(){int res=0;memset(mat,-1,sizeof(mat));for (int u=1; u<=g[0][0]; u++){memset(used,0,sizeof(used));if(dfs(u)) res++;}return res;}int main(){cin>>t;while (t--){memset(g,0,sizeof(g));cin>>g[0][0]>>g[0][1];for (int i=1; i<=g[0][0]; i++){scanf("%d",&n);for (int j=0; j<n; j++){scanf("%d",&m);g[i][m]=1;}}if (hungary()!=g[0][0])cout<<"NO"<<endl;elsecout<<"YES"<<endl;}return 0;}
题意:先判断一个图是不是二分图,如果是二分图则求其最大匹配。
题解: 判断是否为二分图的方法是染色,当一个结点有两种不同的颜色时,则该图必定不是二分图。最大匹配用的是匈牙利算法。
参考代码:
#include<iostream>#include<cstdio>#include<queue>#include<cstring>using namespace std ;int a[500],pre[500],n,m,ans;bool vis[500],map[500][500];bool bfs(){queue<int> que;que.push(1);a[1]=1;while(!que.empty()){int now=que.front();que.pop();for (int i=1; i<=n; i++){if (map[now][i]){if (a[now]==a[i]) return false;else if (a[i]==0){a[i]=-a[now];que.push(i);}}}}return true;}int hungry(int pos){for (int i=1; i<=n; i++){if (!vis[i] && map[pos][i]){vis[i]=true ;if (pre[i]==-1 || hungry(pre[i])){pre[i]=pos;return 1;}}}return 0;}int main(){while(cin>>n>>m){memset(map,false,sizeof(map)) ;memset(pre,-1,sizeof(pre)) ;memset(a,0,sizeof(a)) ;for (int i=0; i<m; i++){int x,y;scanf("%d%d",&x,&y);map[x][y]=true;}if (!bfs()) cout<<"No"<<endl;else{ans=0;for (int i=1; i<=n; i++){memset(vis,false,sizeof(vis));ans+=hungry(i);}cout<<ans<<endl;}}return 0;}