您的位置:首页 > 其它

poj/pku 2594 (最小路径覆盖)

2011-09-27 22:32 435 查看
题目链接:http://poj.org/problem?id=2594

题意描述:有一张图,图中有n个顶点m有向边条边(这里可以有重边),这个图是一个有向无环图(这就保证了它是一个二分图就可以用匈牙利算法来做),问最少需要多少个机器人能够将所有的点都访问完(注意这里的机器人可以重复的经过一个点)

分析:现在的问题就是最少需要找多少条路径使得所有的顶点都能被覆盖,这里如果你直接求最小路径覆盖数的话,答案将是错误的,因为最小路径覆盖求出来的是不相交的路径,但是这题很多时候求出来的解是需要重复走过某条边的,那么就不能用最小路径覆盖做了么? 这个当然可以用最小路径覆盖做,只是需要将原图转换一下,假设某条边需要走两次才是最优的解,第一次走过了该边,下一次就不能经过该边了,但是怎样做才能是下一次不经过该边了,很简单,下一次就跳过该边就好,如何跳过呢,这里求一个传递闭包就可以实现了

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int N=510;
int g

;
int link
;
bool vis
;
int n;
int scan(int u)
{
int v;
for(v=1;v<=n;v++)
if(g[u][v]&&!vis[v])
{
vis[v]=true;
if(link[v]==-1||scan(link[v]))
{
link[v]=u;
return 1;
}
}
return 0;
}
int main ()
{
int m,i,j,x,y,k;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0&&m==0)break;
memset(g,0,sizeof(g));
for(i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
g[x][y]=1;
}

for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(i!=j&&g[i][j]==0&&g[i][k]&&g[k][j])
g[i][j]=1;
memset(link,-1,sizeof(link));
int ans=0;
for(i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis));
ans+=scan(i);
}
printf("%d\n",n-ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: