@Asuna
2017-02-23T13:37:30.000000Z
字数 1613
阅读 820
题解
题意:求一个二分图的最大匹配。
题解:匈牙利算法求二分图最大匹配。
参考代码:
#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;
else
cout<<"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;
}