http://poj.openjudge.cn/practice/1013/
标准做法应该要用正则图的性质,找欧拉回路。
但是我用贪心+匈牙利算法直接就过了,速度也很快(<1s)。
贪心就是每给出一条边,如果这条边的两端都没有被匹配,则先匹配它们。
由于没有直接给出二分图的形式,所以我对每个没有被匹配点都找了一次增广链。
#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;
const int N=100000;
int n,m,r,l[N+5],to[N*20+5],next[N*20+5],match[N+5],q[N+5];
bool b[N+5];
bool find(int i)
{
int j,k,t;
k=l[i];
while(k)
{
j=to[k];
if (!b[j])
{
t=match[j];
match[j]=i;
b[j]=true;
q[++r]=j;
if (!t||find(t))
{
match[i]=j;
return true;
}
match[j]=t;
}
k=next[k];
}
return false;
}
int main(void)
{
int i,j,k,n,m,sum=0;
scanf("%d%d",&n,&m);
k=0;
while(m--)
{
scanf("%d%d",&i,&j);
if (!match[i]&&!match[j])
{
match[i]=j;
match[j]=i;
++sum;
}
to[++k]=j;
next[k]=l[i];
l[i]=k;
to[++k]=i;
next[k]=l[j];
l[j]=k;
}
for(i=1;i<=n;++i)
if (!match[i])
{
r=0;
if (find(i))
++sum;
for(j=1;j<=r;++j)
b[q[j]]=false;
}
for(i=1;i<=n;++i)
if (match[i]>i)
printf("%d %d\n",i,match[i]);
return 0;
}
posted on 2011-05-05 16:19
zxb 阅读(293)
评论(0) 编辑 收藏 引用