这是一道典型的二分匹配的题目,问的是最少需要多少个机器人可以将点全部覆盖。
每个机器人散落在一个点上,每个机器人不能走回路。
公式:
最小路径覆盖数 = 顶点数 - 最大匹配数
最大匹配数用匈牙利算法可求的。
这里的关键是 每个机器人可以走过相同的点,也就是意味着 就算i和j没有边直接相连,但是如果它们都连着k的话,它们之间也可以达到。
这里很明显可以用 Floyd算法,三重循环!
#include <iostream>
using namespace std;
#define MAXV 510
int map[MAXV][MAXV];
bool visit[MAXV];
int check[MAXV];
int n; //表示顶点个数
bool dfs(int v){
int i;
for(i=1;i<=n;i++){
if(!visit[i]&&map[v][i]){
visit[i] = 1;
if(check[i] == -1 || dfs(check[i])){
check[i] = v;
return true;
}
}
}
return false;
}
int hungry(){
int ans = 0;
memset(check,-1,sizeof(check));
for(int i=1;i<=n;i++){
memset(visit,0,sizeof(visit));
if(dfs(i))
ans++;
}
return ans;
}
int main(){
int m; //街道数目
int i,ans,a,b,j,k;
while(cin>>n>>m,n||m){
memset(map,0,sizeof(map));
for(i=0;i<m;i++){
cin>>a>>b;
map[a][b] = 1;
}
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
for(k=1;k<=n;k++){
if(map[i][k]&&map[k][j]){
map[i][j] = 1; //一旦发现i与j之间可以连的话,就不需要循环了
break;
}
}
}
}
ans = n - hungry();
cout<<ans<<endl;
}
}