poj 1422 Air Raid

来源:互联网 发布:如何用js判断是否闰年 编辑:程序博客网 时间:2024/06/10 19:01

题意:有n个路口,m条有向条边,从任意一点出发,不能回到走过的路口。先在要选最少的人遍历所有的路口,路径不能交叉。


分析:这题是一个最小路径覆盖问题。用拆点法建立二分图。求出最大匹配数即可得到答案。

最小路径覆盖数= 原图顶点数 二分图最大匹配数。

PS:对于这个结论,并没有理解,得好好想想~


以下附上代码:

#include <algorithm>#include <iostream>#include <sstream>#include <fstream>#include <cstring>#include <cstdio>#include <vector>#include <cctype>#include <cmath>#include <stack>#include <queue>#include <list>#include <map>#include <set>using namespace std;typedef long long ll;typedef unsigned long long ull;const int maxn = 130;int n,m;int edge[maxn][maxn];int cx[maxn],cy[maxn];bool vis[maxn];void input(){  int u,v;  scanf("%d%d",&n,&m);    for(int i = 0; i <= n; i++){    for(int j = 0; j <= n; j++){      edge[i][j] = 0;    }  }    for(int i = 0; i < m; i++){    scanf("%d%d",&u,&v);    edge[u][v] = 1;  }}int findPath(int u){  for(int v = 1; v <= n; v++){    if(!vis[v] && edge[u][v]){      vis[v] = 1;      if(cy[v] == -1 || findPath(cy[v])){        cx[u] = v;        cy[v] = u;        return 1;      }    }  }  return 0;}int maxMatch(){  int res = 0;  fill(cx,cx+n+1,-1);  fill(cy,cy+n+1,-1);  for(int i = 1; i <= n; i++){    if(cx[i] == -1){      fill(vis,vis+n+1,0);      res += findPath(i);    }  }  return res;}void solve(){  printf("%d\n",n-maxMatch());}int main(){  int t;  scanf("%d",&t);  while(t--){    input();    solve();  }return 0;}


0 0
原创粉丝点击