POJ2594 - Treasure Exploration
Description
给出一个有向无环图
Solution
首先考虑若路径不能相交如何实现:
很明显n条路径一定可以覆盖,即每个顶点上都有一个自己到自己的路径。然后我们尝试合并这n条路径。
把原来的有向图转换成一个二分图,每条边
然后对于路径可以相交的本题,可以先跑一遍
时间复杂度为
O(n3) 。
Code
//Treasure Exploration
#include <cstdio>
#include <cstring>
int const N=500+10;
int n,m; bool ed[N][N];
void Floyd()
{
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
ed[i][j]|=ed[i][k]&ed[k][j];
}
int link[N]; bool used[N];
int find(int u)
{
for(int v=1;v<=n;v++)
{
if(!ed[u][v]||used[v]) continue;
used[v]=true;
if(!link[v]||find(link[v])) {link[v]=u; return true;}
}
return false;
}
int match()
{
int res=0; memset(link,0,sizeof link);
for(int i=1;i<=n;i++)
{
memset(used,0,sizeof used);
if(find(i)) res++;
}
return res;
}
int main()
{
while(true)
{
scanf("%d%d",&n,&m); if(n==0&&m==0) break;
memset(ed,0,sizeof ed);
for(int i=1;i<=m;i++)
{
int u,v; scanf("%d%d",&u,&v);
ed[u][v]=true;
}
Floyd();
printf("%d\n",n-match());
}
return 0;
}
P.S.
多组测试数据,别忘了清数组啊。