题目在: http://poj.org/problem?id=2594
因为是按照分类做题目,所以在明知这个题目是 最小路径覆盖的时候,就匆忙写好代码,提交,结果WA。
检查半天,结果发现题目中的提示:You should notice that the roads of two different robots may contain some same point.
而传统的最小路径覆盖的结果中,不同路径是不能出现重复点的。
所以这个题目中的 两个点之间是否可达就要重新定义了。
因为可以过相同的点,所以可以认为两个点,只要在按照图遍历的方法遍历的时候能遍历的到,就应该是联通的。
按照这个思路可以先用算法将 连接关系扩展,然后用扩展后的连接关系来 求最小路径覆盖:
#include <stdio.h>
#include <memory.h>
#define MAX_NUM 505
int vvAdj[MAX_NUM][MAX_NUM];
bool visit[MAX_NUM];
int matched[MAX_NUM];
int nPoints;
bool dfs(int f)
{
for(int i = 1; i <= nPoints; i++)
{
if(!visit[i] && vvAdj[f][i])
{
visit[i] = true;
if(matched[i] == -1 || dfs(matched[i]))
{
matched[i] = f;
return true;
}
}
}
return false;
}
void GetVVAdjacency()
{
int i,j,k;
for( k = 1; k <= nPoints; k++)
{
for( i = 1; i <= nPoints; i++)
{
for( j = 1; j <= nPoints; j++)
{
if( i != j)
{
if(vvAdj[i][k] && vvAdj[k][j] )
{
vvAdj[i][j] = 1;
}
}
}
}
}
}
int main()
{
int nRoad;
while(scanf("%d%d",&nPoints, &nRoad) )
{
if(nPoints == 0 && nRoad == 0)
{
break;
}
memset(matched, -1, sizeof(matched));
memset(vvAdj, 0, sizeof(vvAdj));
int i;
int f,t;
for( i = 0; i < nRoad; i++)
{
scanf("%d%d", &f, &t);
vvAdj[f][t] = 1;
}
GetVVAdjacency();
int count = 0;
for( i = 1; i <= nPoints; i++)
{
memset(visit, 0, sizeof(visit));
if(dfs(i))
{
count++;
}
}
printf("%d\n", nPoints - count);
}
return 0;
}