poj 1422Air Raid
2012-08-12 10:49
197 查看
最小路径覆盖,给定一个有向图,在这个图上的某些点上放伞兵,可以使伞兵可以走到图上所有的点。且每个点只被一个伞兵走一次。问至少放多少伞兵。
我们可以把问题转化为,在图上的边中选出一些边,使得每个点的如度与出度都不超过1。
我们开始在图上的每个点都放上伞兵,然后每选出一条边,就意味着有一个伞兵可以被取消掉了。也就是说需要的最少伞兵数=点总数-能选出的最大边数。
我们只要求最大边数即可。用二分图匹配,把每个点拆成两个点,分别加入二分图的两个点集,原图中一条由a到b的边在二分图中是一条由第一个点集中的第a个点到第二个点集中的第b个点。也就是第一个点集的点与出边有关,第二个与入边有关。匹配时也就保证了每个点的如度与出度都不超过1。求最大匹配即为能选出的最大边数。
我们可以把问题转化为,在图上的边中选出一些边,使得每个点的如度与出度都不超过1。
我们开始在图上的每个点都放上伞兵,然后每选出一条边,就意味着有一个伞兵可以被取消掉了。也就是说需要的最少伞兵数=点总数-能选出的最大边数。
我们只要求最大边数即可。用二分图匹配,把每个点拆成两个点,分别加入二分图的两个点集,原图中一条由a到b的边在二分图中是一条由第一个点集中的第a个点到第二个点集中的第b个点。也就是第一个点集的点与出边有关,第二个与入边有关。匹配时也就保证了每个点的如度与出度都不超过1。求最大匹配即为能选出的最大边数。
#include<iostream> using namespace std; const int MAXN = 501; bool vis[MAXN]; int result[MAXN]; bool space[MAXN][MAXN]; bool refresh(int i,int n) { for(int j=1;j!=n+1;j++) { if(!vis[j] && space[i][j]==1) { vis[j]=true; if(result[j]==0 || refresh(result[j],n)) { result[j] = i; return true; } } } return false; } int main() { int t,n,m; cin>>t; while(t--) { cin>>n>>m; int ans(0); memset(space,false,sizeof(space)); memset(result,0,sizeof(result)); while(m--) { int a,b;cin>>a>>b; space[a][b] = true; } for(int i=1;i!=n+1;i++) { memset(vis,0,sizeof(vis)); if(refresh(i,n)) ans++; } cout<<(n-ans)<<endl; } return 0; }
相关文章推荐
- poj 1422 Air Raid
- POJ 1422 Air Raid (二分匹配)
- POJ-1422-Air Raid(二分图最小路径覆盖)
- POJ1422 Air Raid
- poj 1422 Air Raid (最小路径覆盖 )
- POJ 1422 Air Raid 及 关于匈牙利算法的理解的小比喻
- poj 1422 Air Raid (二分图匹配)
- poj 1422 Air Raid(最小路径覆盖)
- POJ 1422 Air Raid
- POJ 1422 Air Raid 最小覆盖点
- POJ - 1422 Air Raid 二分图最大匹配
- POJ 1422 Air Raid (最小路径覆盖)
- [POJ]1422-Air Raid(最小路径覆盖)
- POJ 1422 Air Raid(二分图匹配最小路径覆盖)
- POJ - 1422 Air Raid(DAG的最小路径覆盖数)
- poj&nbsp;1422&nbsp;Air&nbsp;Raid(匈牙利&nbsp;DAC图最…
- POJ 1422 Air Raid(DAG最小路径覆盖)
- poj 1422 Air Raid (最小路径覆盖白痴题)
- POJ 1422 Air Raid
- poj 1422 Air Raid (二分匹配)