您的位置:首页 > 产品设计 > UI/UE

pku 1904 king's Quest

2011-07-21 19:35 274 查看
题意:有n个男的,n个女的,每个男的都有自己喜欢的女孩(可以是多个),给你个初始匹配,问你每个男的可以和哪些女的结婚。可以的意思是:这个男的和这个女的结婚后对于其他的人都存在一个女孩能和他结婚分析:匹配的本质是增广路,将问题转化为求强连通分量
代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;

#define N 4050
#define M 250000
#define min(a,b) (((a)<(b))?(a):(b))
int n,e,head
,nxt[M],pnt[M];
int t,top,num,time
,low
,s
,belong
;
char vis
,instack
;
void addedge(int u,int v)
{
pnt[e]=v;
nxt[e]=head[u];
head[u]=e++;
}
void dfs(int u)
{
int i,v,k;
vis[u]=instack[u]=1;
time[u]=low[u]=t++;
s[top++]=u;
for(i=head[u];i!=-1;i=nxt[i])
{
v=pnt[i];
if(vis[v]==0)
{
dfs(v);
low[u]=min(low[u],low[v]);
}
else if(instack[v]&&low[u]>time[v])
low[u]=time[v];
}
if(low[u]==time[u])
{
do{
k=s[--top];
belong[k]=num;
instack[k]=0;
}while(top>0&&k!=u);
num++;
}
}
void tarjan()
{
int i;
t=top=0;num=1;
memset(vis,0,sizeof(vis));
memset(instack,0,sizeof(instack));
for(i=1;i<=n+n;i++)
if(!vis[i])
dfs(i);
}
int ans1[M];
int main()
{
int i,j,k,num,ans;
while(scanf("%d",&n)!=EOF)
{
e=0;memset(head,-1,sizeof(head));
for(i=1;i<=n;i++)
{
scanf("%d",&num);
for(j=0;j<num;j++)
{
scanf("%d",&k);
addedge(i,k+n);
}
}
for(i=1;i<=n;i++)
{
scanf("%d",&k);
addedge(k+n,i);
}
tarjan();
for(i=1;i<=n;i++)
{
ans=num=0;
for(j=head[i];j!=-1;j=nxt[j])
if(belong[i]==belong[pnt[j]])
{
ans++;
ans1[num++]=pnt[j];
}
printf("%d",ans);
sort(ans1,ans1+num);
for(j=0;j<num;j++)
printf(" %d",ans1[j]-n);
printf("\n");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: