POJ-1422-Air Raid-求最小路径覆盖(匈牙利算法)

来源:互联网 发布:渠道营销 知乎 编辑:程序博客网 时间:2024/05/17 04:03

http://poj.org/problem?id=1422

题意:

    一个镇里所有的路都是单向路且不会组成回路。

       派一些伞兵去那个镇里,要到达所有的路口,有一些或者没有伞兵可以不去那些路口,只要其他人能完成这个任务(也就是每个点只被一条路径包含)。每个在一个路口着陆了的伞兵可以沿着街去到其他路口。我们的任务是求出去执行任务的伞兵最少可以是多少个。


显然,每个伞兵,可以走一条路径(可由多条边组成 ),那么就是要最少的路径覆盖掉所有的点

也就是求 最小路径覆盖 ,他在二分图里,等于二分图的最大独立集=n-最大匹配数

 




#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <map>#include <set>#include <vector>#include <iostream>using namespace std; const double pi=acos(-1.0);double eps=0.000001;  //顶点编号从0开始的const int MAXN = 510;int uN,vN;//u,v的数目,使用前面必须赋值int g[MAXN][MAXN];//邻接矩阵int linker[MAXN];bool used[MAXN];bool dfs(int u){for(int v = 0; v < vN;v++)if(g[u][v] && !used[v]){used[v] = true;if(linker[v] == -1 || dfs(linker[v])){linker[v] = u;return true;}}return false;}char sex[505][100],music[505][100],work[505][100];int hungary(){int res = 0;  memset(linker,-1,sizeof(linker));for(int u = 0;u < uN;u++){ memset(used,false,sizeof(used));if(dfs(u))res++;}return res;}int h[505];int main(){int i,j;int n;int t;cin>>t;while(t--){int k;memset(g,0,sizeof(g));cin>>n>>k;int x,y;for (i=1;i<=k;i++) {scanf("%d%d",&x,&y); g[x-1][y-1]=1;}uN=vN=n; int ret=hungary(); //得到最大匹配数,//要求最小路径覆盖=最大独立集=n-最大匹配数 printf("%d\n",n-ret);} return 0; }


0 0
原创粉丝点击