poj 1904
来源:互联网 发布:钢琴入门自学教程知乎 编辑:程序博客网 时间:2024/04/30 15:32
题目意思:有N对男女,一个男的可以喜欢多个女的,要求这样一个匹配,使得一个男的尽可以多的和他喜欢的女的结婚,同时保证所有男的均有伴侣。
这题不是二分图匹配,但是考查了二分图匹配的思想,按照这个思想建图即可解决。首先是按照题中的要求,对于每对男女u,v,连边(u,v+n),n为对数,最后给出的那个匹配是正确的,则对于每个女生v,连边(v,u),u为男生。然后求强连通分量,对于每个男生,所有和他在同一个强连通分量里的女生都可以做他的老婆,只要计数排好序输出即可。
之所以说考察了二分图匹配的思想,是因为这里考查了匈牙利算法的找增广路的过程,大家可以照着这个图,模拟匈牙利算法,就可以明白。它是在保证了前一个结点有匹配的基础上,找到自己的匹配。如样例中的1号男生,他若选了2号女生,则同一个强连通分量里的2号男生可以顺着“增广边”(5->1)找到1号女生,则一过程实际就是匈牙利算法找增广路的过程。
以下是代码,3000+ms,不知牛人是怎样300+ms的,因为数据量很大。
- #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=400110;
const int N=4200;
struct node
{
int v;
int next;
}edge[M];
int head[N],num;
bool vis[N],instack[N];
int stack[10*N],belong[N],top,bcnt,dindex,dep[N],low[N];
int n,m; - void init()
{
int i;
for(i=0;i<=2*n+5;i++)
head[i]=-1;
num=0;
} - void addege(int u,int v)
{
edge[num].v=v;
edge[num].next=head[u];
head[u]=num++;
} - void dfs(int i)
{
int j,v;
dep[i]=low[i]=++dindex;
instack[i]=1;
stack[++top]=i;
for(j=head[i];j!=-1;j=edge[j].next)
{
v=edge[j].v;
if(!dep[v])
{
dfs(v);
if(low[v]<low[i])
low[i]=low[v];
}
else if(instack[v] && dep[v]<low[i])
low[i]=dep[v];
}
if(dep[i]==low[i])
{
bcnt++;
do
{
j=stack[top--];
instack[j]=0;
belong[j]=bcnt;
}while(j!=i);
}
} - void tarjan()
{
int i;
top=bcnt=dindex=0;
memset(dep,0,sizeof(dep));
memset(vis,0,sizeof(vis));
for(i=1;i<=n;i++)
if(!dep[i])
{
dfs(i);
}
} - int rec[N];
void solve()
{
int i,j,cnt;
for(i=1;i<=n;i++)
{
cnt=0;
for(j=head[i];j!=-1;j=edge[j].next)
if(belong[edge[j].v]==belong[i])
rec[cnt++]=edge[j].v-n;
sort(rec,rec+cnt);
printf("%d",cnt);
for(j=0;j<cnt;j++)
printf(" %d",rec[j]);
printf("/n");
}
} - int main()
{
while(scanf("%d",&n)==1)
{
init();
int i,j;
int a,b,c;
for(i=1;i<=n;i++)
{
scanf("%d",&a);
while(a--)
{
scanf("%d",&b);
addege(i,b+n);
}
}
for(i=1;i<=n;i++)
{
scanf("%d",&b);
addege(b+n,i);
}
tarjan();
solve();
}
return 0;
}
- poj 1904
- poj 1904
- poj-1904
- POJ 1904 强连通
- poj 1904 强连通
- POJ 1904 HDU 4685
- poj 1904 Tarjan
- POJ 1904 思路题
- POJ
- poj
- POJ
- POJ
- poj
- poj
- POJ
- POJ
- poj
- POJ
- 敏捷的定义
- MTK 网络通信详解
- 关于visual studio 2008试用版评估期已结束解决
- To Symantec
- MTK总结(一)
- poj 1904
- Web应用中基于XML的Excel报表设计
- VB.net下几种判断的执行效率
- MTK总结(二)
- 对图的构造及广搜和深搜
- Qt中文显示
- MTK总结(三)
- 昨天是520,今天是521
- 解读linux的/proc下的statm、maps、memmap 内存信息文件分析