[BZOJ]2150: 部落战争 二分图匹配
2017-09-12 13:36
239 查看
Description
lanzerb的部落在A国的上部,他们不满天寒地冻的环境,于是准备向A国的下部征战来获得更大的领土。 A国是一个M*N的矩阵,其中某些地方是城镇,某些地方是高山深涧无人居住。lanzerb把自己的部落分成若干支军队,他们约定: 1. 每支军队可以从任意一个城镇出发,并只能从上往向下征战,不能回头。途中只能经过城镇,不能经过高山深涧。 2. 如果某个城镇被某支军队到过,则其他军队不能再去那个城镇了。 3. 每支军队都可以在任意一个城镇停止征战。 4. 所有军队都很奇怪,他们走的方法有点像国际象棋中的马。不过马每次只能走1*2的路线,而他们只能走R*C的路线。 lanzerb的野心使得他的目标是统一全国,但是兵力的限制使得他们在配备人手时力不从心。假设他们每支军队都能顺利占领这支军队经过的所有城镇,请你帮lanzerb算算至少要多少支军队才能完成统一全国的大业。
lanzerb的部落在A国的上部,他们不满天寒地冻的环境,于是准备向A国的下部征战来获得更大的领土。 A国是一个M*N的矩阵,其中某些地方是城镇,某些地方是高山深涧无人居住。lanzerb把自己的部落分成若干支军队,他们约定: 1. 每支军队可以从任意一个城镇出发,并只能从上往向下征战,不能回头。途中只能经过城镇,不能经过高山深涧。 2. 如果某个城镇被某支军队到过,则其他军队不能再去那个城镇了。 3. 每支军队都可以在任意一个城镇停止征战。 4. 所有军队都很奇怪,他们走的方法有点像国际象棋中的马。不过马每次只能走1*2的路线,而他们只能走R*C的路线。 lanzerb的野心使得他的目标是统一全国,但是兵力的限制使得他们在配备人手时力不从心。假设他们每支军队都能顺利占领这支军队经过的所有城镇,请你帮lanzerb算算至少要多少支军队才能完成统一全国的大业。
题解:
这个有向无环图为什么可以用二分图匹配呢?FYC大神告诉我:比如说对于一条路径1->2->3->4,直接建二分图,那么最后1、2、3都会找到匹配,最大匹配数为3。实际上,对于每一条路径,只有结尾的点没有匹配,其他的点都能找到匹配,所以每一个没有匹配的点实际上代表了一条路径,所以最小路径覆盖=总点数-最大匹配。代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=60; int n,m,r,c,num[maxn][maxn],map[maxn][maxn],T=0; char str[maxn]; int tx[10],ty[10]; bool in(int x,int y) { if(x>0&&y>0&&x<=n&y<=m)return true; return false; } struct Edge{int y,next;}e[maxn*maxn*8]; int last[maxn*maxn],len=0,sum=0; void ins(int x,int y) { int t=++len; e[t].y=y;e[t].next=last[x];last[x]=t; } int chw[maxn*maxn],match[maxn*maxn]; bool findm(int x) { for(int i=last[x];i;i=e[i].next) { int y=e[i].y; if(chw[y]!=T) { chw[y]=T; if(!match[y]||findm(match[y])) { match[y]=x; return true; } } } return false; } int main() { scanf("%d%d%d%d",&n,&m,&r,&c); tx[0]=tx[1]=r;tx[2]=tx[3]=c; ty[0]=-c;ty[1]=c;ty[2]=-r;ty[3]=r; for(int i=1;i<=n;i++) { scanf("%s",str+1); for(int j=1;j<=m;j++) map[i][j]=(str[j]=='.'?0:1); } int z=0,ans=0; for(int i=1;i<=n;i++) for(int j=1; 10198 j<=m;j++) num[i][j]=++z; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(!map[i][j]) { sum++; for(int k=0;k<4;k++) { int x=i+tx[k],y=j+ty[k]; if(in(x,y)&&!map[x][y])ins(num[i][j],num[x][y]); } } for(int i=1;i<=n*m;i++) { T++; if(findm(i))ans++; } printf("%d",sum-ans); }
相关文章推荐
- [BZOJ2150]部落战争(二分图匹配)
- BZOJ 2150: 部落战争 [二分图匹配][最小路径覆盖]
- [BZOJ2150]部落战争-二分图匹配
- 【bzoj2150】 部落战争 二分图匹配
- bzoj 2150: 部落战争 最小路径覆盖的做法+证明。
- 【BZOJ2150】部落战争 最小流
- 【BZOJ】2150 部落战争 二分图
- BZOJ 2150: 部落战争 二分图最小路径覆盖
- BZOJ 2150 cogs 1861 [国家集训队2011]部落战争
- bzoj 2150: 部落战争 (最小路径覆盖)
- BZOJ2150 部落战争 【带上下界最小流】
- 【bzoj2150】部落战争 有上下界最小流
- BZOJ 2150: 部落战争 最大流
- [bzoj2150]部落战争_二分图最小路径覆盖
- bzoj-2150 部落战争
- 【最小路径覆盖】【二分图】【最大流】【Dinic】bzoj2150 部落战争
- [bzoj2150] 部落战争(二分图最小边覆盖)
- BZOJ2150部落战争
- bzoj2150 部落战争
- BZOJ 2150 部落战争 最小路径覆盖 二分图最大匹配