【匈牙利】HDU5093[Battle ships]题解
来源:互联网 发布:js防水卷材和丙纶防水 编辑:程序博客网 时间:2024/05/23 13:25
题目概述
一张网格图,每个格子是海,浮冰或冰山,一只船(只占一个格子)只能放在海上。两只船放在同行同列需要满足他们之间至少有一座冰山。求最多能放多少船。
解题报告
一行一列只能放一个,一下就想到二分图最大匹配了,但是有障碍物,怎么办?其实问题的本质还是一样的,只不过我们需要这么处理:
由于出现了障碍物,“一行”和“一列”已经不能是原来意义上的一行和一列了。在同一行,如果被障碍物隔开,其实应该视作“多行”。也就是说我们可以把每个格子标两个号:“行”号和“列”号,障碍和浮冰处没有标号。在一行(一列)中,如果被障碍物隔开,就需要将之后的格子的标号+1,但被浮冰隔开则没有影响。这么处理之后,直接刷二分图最大匹配就行了。
示例程序
#include<cstdio>#include<cstring>using namespace std;const int maxn=50,maxm=50,maxt=maxn*maxm;int te,n,m,sumx,sumy,ans;char pic[maxn+5][maxm+5];int idx[maxn+5][maxm+5],idy[maxn+5][maxm+5];int E,lnk[maxt/2+5],who[maxt/2+5],son[maxt+5],nxt[maxt+5];bool vis[maxt/2+5];char getrch() {char ch=getchar();while (ch!='*'&&ch!='o'&&ch!='#') ch=getchar();return ch;}void make_x() //为行标号{ sumx=0;memset(idx,0,sizeof(idx)); for (int i=1,j=1;i<=n;i++,j=1) while (j<=m) { for (;j<=m&&pic[i][j]=='#';j++);sumx+=j<=m; for (;j<=m&&pic[i][j]!='#';j++) if (pic[i][j]=='*') idx[i][j]=sumx; }}void make_y() //为列标号{ sumy=0;memset(idy,0,sizeof(idy)); for (int j=1,i=1;j<=m;j++,i=1) while (i<=n) { for (;i<=n&&pic[i][j]=='#';i++);sumy+=i<=n; for (;i<=n&&pic[i][j]!='#';i++) if (pic[i][j]=='*') idy[i][j]=sumy; }}void Add(int x,int y) {son[++E]=y;nxt[E]=lnk[x];lnk[x]=E;}bool Find(int x){ if (vis[x]) return false;vis[x]=true; for (int j=lnk[x];j;j=nxt[j]) if (!who[son[j]]||Find(who[son[j]])) { who[son[j]]=x; return true; } return false;}int main(){ freopen("program.in","r",stdin); freopen("program.out","w",stdout); scanf("%d",&te); while (te--) { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) pic[i][j]=getrch(); make_x();make_y(); E=0;memset(lnk,0,sizeof(lnk)); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (idx[i][j]&&idy[i][j]) //i,j放船意味着idx[i][j]->idy[i][j] Add(idx[i][j],idy[i][j]); ans=0;memset(who,0,sizeof(who)); for (int i=1;i<=sumx;i++) //最大匹配 memset(vis,0,sizeof(vis)),ans+=Find(i); printf("%d\n",ans); } return 0;}
阅读全文
0 0
- 【匈牙利】HDU5093[Battle ships]题解
- HDU5093 Battle ships (BZOJ4554)
- HDU5093 Battle ships (二分图)
- hdu5093 Battle ships 二分图匹配
- hdu5093 Battle ships 二分图匹配
- HDU 5093 Battle ships [二分图匹配] [匈牙利算法]
- Battle Ships
- ZOJ 3623 Battle Ships
- zoj 3623 Battle Ships
- ZOJ 3623 Battle Ships
- zoj3623 Battle Ships DP
- Battle Ships(完全背包)
- ZOJ3623 Battle Ships
- hdu 5093 Battle ships
- ZOJ 3623 Battle Ships
- ZOJ 3623 Battle Ships
- zoj 3623 battle ships
- zoj3623 Battle Ships
- CButtonST使用技巧
- [BZOJ 3674]可持久化并查集加强版:可持久化并查集
- eclipse 中文乱码问题解决方案汇总
- 定时器延迟加载
- 【C++】【LeetCode】29. Divide Two Integers
- 【匈牙利】HDU5093[Battle ships]题解
- java学习路线
- thread12
- 大学生活随笔
- XML中Schema的概述
- Hibernate一对一双向映射 注解方式
- Spring_demo2_Annotation_AutoWired
- servlet
- Editor_EditorWindow学习06