poj 2594 Treasure Exploration

题意:类似于1422,也是最小路径覆盖,但是一定要仔细看题

思路:顶点数-最大匹配

要用floyd,因为A->B,和B->C,可以得到A->C,但是一旦匹配了A->B,A就与C不连通了

囧,看discuss才明白的……

/*
因为每个点可以属于多条路,如果只属于
其中一条路的话,匹配后,另外连接这点
的路可能就断了
2011-7-22
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <climits>
#include <algorithm>
#include <functional>
#include <cstdlib>
#include <queue>
#include <vector>
#include <stack>
#define nMax 505
using namespace std;
bool mat[nMax][nMax], used[nMax];
int maty[nMax];
int n, m;

bool path(int u)
{
for(int i=1; i<=n; i++)
{
if(mat[u][i] && !used[i])
{
used[i]=1;
if(maty[i]==-1 || path(maty[i]))
{
maty[i]=u;
return 1;
}
}
}
return 0;
}

int MaxMatch()
{
int ret=0;
memset(maty, -1, sizeof(maty));
for(int i=1; i<=n; i++)
{
memset(used, 0, sizeof(used));
if(path(i)) ret++;
}
return ret;
}

void floyd()
{
for(int i=1; i<=n; i++)
for(int k=1; k<=n; k++)
for(int j=1; j<=n; j++)
if( mat[k][i] && mat[i][j] )
mat[k][j] = 1;
}

int main()
{
while(scanf("%d%d", &n, &m), n+m)
{
memset(mat, 0, sizeof(mat));
for(int i=0; i<m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
mat[x][y]=1;
}
floyd();
printf("%d\n", n-MaxMatch());
}
return 0;
}
原文地址:https://www.cnblogs.com/FreeAquar/p/2114523.html