您的位置:首页 > 大数据 > 人工智能

poj1422-最小路径覆盖(不交叉)&二分图-Air Raid

2017-11-28 15:24 465 查看
https://vjudge.net/problem/POJ-1422

给定一个图。点代表小城镇,边代表小城镇的路,你可以再一个点投一个伞兵,那个sb可以出发,经过任何他所经过的点,问你最少投多少伞兵。

要求①:伞兵不可以交叉。

思路① dfs?但是是有向图,不是求连通分量那种。

② topsort也是不行的,因为只能求topsort并不能确定有分叉的情况。

③ 正解,二分图求 最小路径覆盖。

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
/*
*/
const int maxn=200;
int mp[maxn][maxn];
int linker[maxn];
bool used[maxn];
int m,n;
bool dfs(int u){
for(int v=1;v<=m;v++){
if(mp[u][v]&&!used[v]){
used[v]=true;
if(linker[v]==-1||dfs(linker[v])){
linker[v]=u;
return true;
}
}
}
return false;
}
int t;
int main()
{   int a,b;
scanf("%d",&t);
while(t--){
memset(mp,0,sizeof(mp));
scanf("%d%d",&m,&n);
for(int i=0;i<n;i++){
scanf("%d%d",&a,&b);
mp[a][b]=1;
}
/* for(int k=1;k<=m;k++){
for(int i=1;i<=m;i++){
for(int j=1;j<=m;j++)
if(mp[i][k]&&mp[k][j])
mp[i][j]=1;
}
}*/
int res=0;
memset(linker,-1,sizeof(linker));
for(int i=1;i<=m;i++){
memset(used,0,sizeof(used));
if(dfs(i)){
res++;
}
}
// cout<<res<<endl;
printf("%d\n",m-res);//最小路径覆盖就是顶点数-匹配数
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: