您的位置:首页 > 其它

ZOJ 3642 Just Another Information Sharing Problem【二分图多重匹配】

2012-08-26 19:45 405 查看
题意: 有N 个人,知道了每个人知道的信息,和它最多能告诉别人的信息数目,问编号为 m 的人最多能知道的信息条数是多少。

分析: 由于信息的编号比较大,所以先需要进行离散化。

每个人和自己知道的每个信息之间都有一条边相连,

每个人匹配容量为 他最多能告诉别人的信息数目。

#include<stdio.h>
#include<string.h>
#define maxn 222
#define clr(x)memset(x,0,sizeof(x))
int cap[maxn];
int map[maxn][maxn];
int vlink[maxn];
int link[maxn][maxn];                 //link[i][j] 表示与i点匹配好的第j个点
int v[maxn];
int n,m;
int find(int x)
{
int i,j;
for(i=0;i<n;i++)
{
if(map[x][i]&&!v[i])
{
v[i]=1;
if(vlink[i]<cap[i])         //i点的匹配数尚未达到上限,可直接匹配
{
link[i][vlink[i]++]=x;  //x做为i的第vlink[i]个匹配点
return 1;
}                           //如果i点的匹配数已经达到上限,则遍历之前与i匹配的点
for(j=0;j<vlink[i];j++)     //若它能与别的点匹配,则将位置让出来给 x
{
if(find(link[i][j]))    //能与其他点匹配
{
link[i][j]=x;       //让出位置给 x
return 1;
}
}
}
}
return 0;
}
int man[maxn][maxn];
int tt[maxn];
int vis[1000005];
int main()
{
int i,j,flag,p,mm,tot,cc,res;
while(scanf("%d",&n)!=EOF)
{
clr(tt);
clr(vis);
tot=1;
for(i=0;i<n;i++)
{
scanf("%d%d%d",&mm,&p,&cap[i]);
while(mm--)
{
scanf("%d",&p);
if(vis[p]==0)
vis[p]=tot++;
man[i][tt[i]++]=vis[p];
}
}
memset(vlink,0,sizeof(vlink));
scanf("%d",&cc);
cap[cc-1]=222;
clr(map);
for(i=0;i<n;i++)
for(j=0;j<tt[i];j++)
map[man[i][j]][i]=1;
m=tot-1;
int res=0;
for(i=1;i<=m;i++)
{
memset(v,0,sizeof(v));
if(find(i))
res++;
}
printf("%d\n",res);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: