POJ1422 Air Raid【二分图最小路径覆盖】
2015-04-04 11:03
225 查看
题目链接:
http://poj.org/problem?id=1422
题目大意:
有N个地点和M条有向街道,现在要在点上放一些伞兵,伞兵可以沿着有向街道走,直到不能走为止。
每条边只能被一个伞兵走一次。问:至少放多少伞兵,能使伞兵可以走到图上所有的点。
思路:
很明显的最小路径覆盖问题。先转换为二分图,先将N个点每个点拆成两个点,左边是1~N个点,右
边也是1~N个点。将有向街道变为左边点指向右边点的边。
因为二分图最小路径覆盖 = 点数 - 二分图最大匹配数,则求出结果就是放的最少伞兵数。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAXN = 140;
bool Map[MAXN][MAXN],Mask[MAXN];
int NX,NY;
int cx[MAXN],cy[MAXN];
int FindPath(int u)
{
for(int i = 1; i <= NY; ++i)
{
if(Map[u][i] && !Mask[i])
{
Mask[i] = 1;
if(cy[i] == -1 || FindPath(cy[i]))
{
cy[i] = u;
cx[u] = i;
return 1;
}
}
}
return 0;
}
int MaxMatch()
{
for(int i = 1; i <= NX; ++i)
cx[i] = -1;
for(int i = 1; i <= NY; ++i)
cy[i] = -1;
int res = 0;
for(int i = 1; i <= NX; ++i)
{
if(cx[i] == -1)
{
for(int j = 1; j <= NY; ++j)
Mask[j] = 0;
res += FindPath(i);
}
}
return res;
}
int main()
{
int T,N,M,u,v;
scanf("%d",&T);
while(T--)
{
memset(Map,0,sizeof(Map));
scanf("%d%d",&N,&M);
for(int i = 1; i<= M; ++i)
{
scanf("%d%d",&u,&v);
Map[u][v] = 1;
}
NX = NY = N;
printf("%d\n",N-MaxMatch());
}
return 0;
}
http://poj.org/problem?id=1422
题目大意:
有N个地点和M条有向街道,现在要在点上放一些伞兵,伞兵可以沿着有向街道走,直到不能走为止。
每条边只能被一个伞兵走一次。问:至少放多少伞兵,能使伞兵可以走到图上所有的点。
思路:
很明显的最小路径覆盖问题。先转换为二分图,先将N个点每个点拆成两个点,左边是1~N个点,右
边也是1~N个点。将有向街道变为左边点指向右边点的边。
因为二分图最小路径覆盖 = 点数 - 二分图最大匹配数,则求出结果就是放的最少伞兵数。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAXN = 140;
bool Map[MAXN][MAXN],Mask[MAXN];
int NX,NY;
int cx[MAXN],cy[MAXN];
int FindPath(int u)
{
for(int i = 1; i <= NY; ++i)
{
if(Map[u][i] && !Mask[i])
{
Mask[i] = 1;
if(cy[i] == -1 || FindPath(cy[i]))
{
cy[i] = u;
cx[u] = i;
return 1;
}
}
}
return 0;
}
int MaxMatch()
{
for(int i = 1; i <= NX; ++i)
cx[i] = -1;
for(int i = 1; i <= NY; ++i)
cy[i] = -1;
int res = 0;
for(int i = 1; i <= NX; ++i)
{
if(cx[i] == -1)
{
for(int j = 1; j <= NY; ++j)
Mask[j] = 0;
res += FindPath(i);
}
}
return res;
}
int main()
{
int T,N,M,u,v;
scanf("%d",&T);
while(T--)
{
memset(Map,0,sizeof(Map));
scanf("%d%d",&N,&M);
for(int i = 1; i<= M; ++i)
{
scanf("%d%d",&u,&v);
Map[u][v] = 1;
}
NX = NY = N;
printf("%d\n",N-MaxMatch());
}
return 0;
}
相关文章推荐
- poj1422-最小路径覆盖(不交叉)&二分图-Air Raid
- POJ 1422Air Raid(二分图最大匹配之最小路径覆盖)
- POJ-1422-Air Raid (二分图 最小路径覆盖)
- HDOJ 1151 Air Raid(二分图最小路径覆盖)
- HDOJ 题目1151 Air Raid(二分图,最小路径覆盖)
- POJ 题目1422 Air Raid(二分图最小路径覆盖)
- POJ1422 Air Raid 【DAG最小路径覆盖】
- Air Raid (二分图最小路径覆盖)
- hdu1151 二分图(无回路有向图)的最小路径覆盖 Air Raid
- POJ 1422 && ZOJ 1525 --Air Raid【二分图 && 最小路径覆盖】
- POJ 1422-Air Raid(二分图_最小路径覆盖)
- 最小路径覆盖(二分图最大匹配):Air Raid
- POJ 1422 Air Raid - 最小路径覆盖(二分图)-易错题
- POJ1422 Air Raid 【DAG最小路径覆盖】
- HDU1511 Air Raid(二分图,最小路径覆盖)
- hdu 1151 Air Raid(二分图最小路径覆盖)
- POJ1422——Air Raid(二分图,最小路径覆盖)
- HDOJ---1151 Air Raid[匈牙利算法:最小路径覆盖数=原图顶点数–二分图最大匹配数]
- HDU1151_Air Raid(二分图/最小路径覆盖=n-最大匹配)
- poj 1422 Air Raid(最小路径覆盖 + 二分图最大匹配)