POJ 1422 二分匹配 最小路径覆盖(邻接表实现)
2016-07-22 11:02
330 查看
题意:一个地图上有n个小镇,以及连接着其中两个小镇的有向边,而且这些边无法形成回路。现在选择一些小镇空降士兵(1个小镇最多1个士兵),士兵能沿着边走到尽头,问最少空降几个士兵,能遍历完所有的小镇。
思路:匈牙利算法求最小路径覆盖:在一个有向图中,路径覆盖就是在图中找一些路径,使之覆盖了图中的所有顶点,且任何一个顶点有且只有一条路径与之关联;(如果把这些路径中的每条路径从它的起始点走到它的终点,那么恰好可以经过图中的每个顶点一次且仅一次);解决此类问题可以建立一个二分图模型。把所有顶点i拆成两个:X结点集中的i和Y结点集中的i’,如果有边i->j,则在二分图中引入边i->j’,设二分图最大匹配为m,则结果就是n-m
思路:匈牙利算法求最小路径覆盖:在一个有向图中,路径覆盖就是在图中找一些路径,使之覆盖了图中的所有顶点,且任何一个顶点有且只有一条路径与之关联;(如果把这些路径中的每条路径从它的起始点走到它的终点,那么恰好可以经过图中的每个顶点一次且仅一次);解决此类问题可以建立一个二分图模型。把所有顶点i拆成两个:X结点集中的i和Y结点集中的i’,如果有边i->j,则在二分图中引入边i->j’,设二分图最大匹配为m,则结果就是n-m
#include<cstring> #include<cstdio> #include<iostream> #include<cmath> #include<algorithm> #include<queue> #include<vector> using namespace std; #define LL long long #define INF 0x3f3f3f3f const int MAXN=1505;//这个值要超过两边个数的较大者,因为有linker int linker[MAXN]; bool used[MAXN]; vector<int>mp[MAXN]; int uN; bool dfs(int u) { for(int i=0;i<mp[u].size();i++) { if(!used[mp[u][i]]) { used[mp[u][i]]=true; if(linker[mp[u][i]]==-1||dfs(linker[mp[u][i]])) { linker[mp[u][i]]=u; return true; } } } return false; } int hungary() { int u; int res=0; memset(linker,-1,sizeof(linker)); for(u=1;u<=uN;u++) { memset(used,false,sizeof(used)); if(dfs(u)) res++; } return res; } int u,v; int T,k; int main(){ scanf("%d",&T); while(T--){ scanf("%d%d",&uN,&k); for(int i=1;i<=uN;i++)mp[i].clear(); while(k--){ scanf("%d%d",&u,&v); mp[u].push_back(v); } printf("%d\n",uN-hungary()); } return 0; }
相关文章推荐
- 《Java源码分析》:Vector
- python split()函数详解
- RSA算法原理(二)
- Redis内存使用优化与存储
- JUnit教程 --使用@Ignore注解
- 【Mac】使用技巧
- CPU调优
- windows安装mysql5.7zip版方法
- <Python进阶读书笔记>之(一) 函数不定参数传递
- 北斗系统基础知识2(北斗一代定位原理详述)
- 正则表达
- Spring + RMI
- C++ 局部静态变量,全局变量,全局静态变量,局部变量的区别和联系
- 块级作用域变量
- Centos6.6中Apache服务器的安装
- 线程的应用之车票
- PAT-B 1030. 完美数列
- 字符串值一旦初始化就不会被改变
- JAVA修饰符的详细介绍(public protect,default, private,final,abstract)
- gzip解压