hdu 1045 Fire Net 二分图匹配 && HDU-1281-棋盘游戏
题意:任意两个个‘车’不能出现在同一行或同一列,当然如果他们中间有墙的话那就没有什么事,问最多能放多少个‘车’
代码+注释:
1 //二分图最大匹配问题
2 //难点在建图方面,如果这个图里面一道墙也没有,那么可以说就是在横坐标(1...n)和纵坐标(1...n)
3 //中个挑选出来一个,那个点就是我们要放置炮台的地方,么个点只能用一次,这样就能保证正确性
4 //现在现在里面有墙了,在横坐标方面那么看到一个墙就把横坐标的选择数加1,每次换行也加1
5 //纵坐标也做相应处理,那么我们就可以得到两个集合,一个横坐标集合,一个纵坐标集合
6 //我们现在就是从这两个集合中选取元素,集合中元素的意义和没有墙时候的一样
7 //但是他们并不是随意搭配,只有从两个集合中拿去的两个值,在原图中出现的位置相同才可以搭边
8 #include<stdio.h>
9 #include<algorithm>
10 #include<string.h>
11 #include<iostream>
12 #include<queue>
13 using namespace std;
14 const int maxn=20;
15 char maps[maxn][maxn];
16 int link[maxn][maxn],used[maxn],id1[maxn][maxn],flag[maxn],id2[maxn][maxn];
17 int n,lcnt,rcnt;
18 bool dfs(int x)
19 {
20 for(int i=1;i<=lcnt;i++)
21 {
22 if(link[x][i] && !used[i])
23 {
24 used[i]=1;
25 if(flag[i]==0 || dfs(flag[i]))
26 {
27 flag[i]=x;
28 return 1;
29 }
30 }
31 }
32 return 0;
33 }
34 int match()
35 {
36 int ans=0;
37 memset(flag,0,sizeof(flag));
38 for(int i=1;i<=rcnt;++i)
39 {
40 memset(used,0,sizeof(used));
41 ans+=dfs(i);
42 }
43 return ans;
44 }
45 int main()
46 {
47 while(~scanf("%d",&n)&&n)
48 {
49 rcnt=lcnt=0;
50 memset(link,0,sizeof(link));
51 memset(id1,0,sizeof(id1));
52 memset(id2,0,sizeof(id2));
53 for(int i=1;i<=n;++i)
54 scanf("%s",maps[i]+1);
55 for(int i=1;i<=n;++i)
56 {
57 for(int j=1;j<=n;++j)
58 {
59 if(maps[i][j]=='.')
60 {
61 if(j-1==0 || maps[i][j-1]=='X') rcnt++;
62 id1[i][j]=rcnt;
63 }
64 }
65 }
66 for(int j=1;j<=n;++j)
67 {
68 for(int i=1;i<=n;++i)
69 {
70 if(maps[i][j]=='.')
71 {
72 if(i-1==0 || maps[i-1][j]=='X') lcnt++;
73 id2[i][j]=lcnt;
74 }
75 }
76 }
77 for(int i=1;i<=n;++i)
78 {
79 for(int j=1;j<=n;++j)
80 {
81 link[id1[i][j]][id2[i][j]]=1;
82 }
83 }
84 printf("%d\n",match());
85 }
86 return 0;
87 }
HDU-1281-棋盘游戏:
题意:这道题黑心那个一道题可不是完全一样,这上面可是没有墙这个东西,所以就是明显的二分图最大匹配,一个集合是对应的列,另一个集合是行
一个匹配边在棋盘上面就是一个具体的位置(因为行和列已经确定而且每个点只能使用一次)
代码:
1 #include<stdio.h>
2 #include<algorithm>
3 #include<string.h>
4 #include<iostream>
5 #include<queue>
6 using namespace std;
7 const int maxn=1005;
8 int match[maxn],visit[maxn],n,id1,id2,m,grap[maxn][maxn],w[maxn][maxn],w1[maxn][maxn],w2[maxn][maxn];
9 int dfs_solve(int x)
10 {
11 for(int i=1;i<=id2;++i)
12 {
13 if(grap[x][i] && !visit[i])
14 {
15 visit[i]=1;
16 if(match[i]==0 || dfs_solve(match[i]))
17 {
18 match[i]=x;
19 return 1;
20 }
21 }
22 }
23 return 0;
24 }
25 int hungan()
26 {
27 memset(match,0,sizeof(match));
28 int sum=0;
29 for(int i=1;i<=id1;++i)
30 {
31 memset(visit,0,sizeof(visit));
32 sum+=dfs_solve(i);
33 }
34 return sum;
35 }
36 int main()
37 {
38 int n,m,k,e=0;
39 while(~scanf("%d%d%d",&n,&m,&k))
40 {
41 memset(grap,0,sizeof(grap));
42 while(k--)
43 {
44 int a,b;
45 scanf("%d%d",&a,&b);
46 grap[a][b]=1;
47 }
48 id1=n; //这个题目和A题的区别就在于,本题目上的一句话“注意不能放车的地方不影响车的互相攻击”
49 id2=m; //所以这个题目可以看做简单的(1..n)和(1...m)的匹配
50 int ans=hungan();
51 int temp=0;
52 for(int i=1;i<=n;++i)
53 {
54 for(int j=1;j<=m;++j)
55 {
56 if(grap[i][j])
57 {
58 grap[i][j]=0;
59 int su=hungan();
60 if(su<ans) temp++;//,printf("%d\n",su);
61 grap[i][j]=1;
62 }
63 }
64 }
65 printf("Board %d have %d important blanks for %d chessmen.\n",++e,temp,ans);
66 }
67 return 0;
68 }
hdu 1045 Fire Net 二分图匹配 && HDU-1281-棋盘游戏的更多相关文章
- HDU 1045 Fire Net 二分图建图
HDU 1045 题意: 在一个n*n地图中,有许多可以挡住子弹的墙,问最多可以放几个炮台,使得炮台不会相互损害.炮台会向四面发射子弹. 思路: 把行列分开做,先处理行,把同一行中相互联通的点缩成一个 ...
- hdu 1045 Fire Net(二分匹配 or 暴搜)
Fire Net Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- HDU - 1045 Fire Net (二分图最大匹配-匈牙利算法)
(点击此处查看原题) 匈牙利算法简介 个人认为这个算法是一种贪心+暴力的算法,对于二分图的两部X和Y,记x为X部一点,y为Y部一点,我们枚举X的每个点x,如果Y部存在匹配的点y并且y没有被其他的x匹配 ...
- HDU 1045 Fire Net(行列匹配变形+缩点建图)
题意:n*n的棋盘上放置房子.同一方同一列不能有两个,除非他们之间被墙隔开,这种话. 把原始图分别按行和列缩点 建图:横竖分区.先看每一列.同一列相连的空地同一时候看成一个点,显然这种区域不可以同一时 ...
- HDOJ(HDU).1045 Fire Net (DFS)
HDOJ(HDU).1045 Fire Net [从零开始DFS(7)] 点我挑战题目 从零开始DFS HDOJ.1342 Lotto [从零开始DFS(0)] - DFS思想与框架/双重DFS HD ...
- HDU 1045 Fire Net 【连通块的压缩 二分图匹配】
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others) ...
- hdu 1045 Fire Net(二分图)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1045 题目大意为给定一个最大为4*4的棋盘,棋盘可以放置堡垒,处在同一行或者同一列的堡垒可以相互攻击, ...
- HDU 1045(Fire Net)题解
以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 给定大小的棋盘中部分格子存在可以阻止互相攻击的墙,问棋盘中可以放置最多多少个可以横纵攻击炮塔. [题目分析] 这题本来在搜索专题 ...
- hdu 1045 Fire Net(最小覆盖点+构图(缩点))
http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit:1000MS Memory Limit:32768KB ...
随机推荐
- readhat6.5下安装weblogic10.3.6
转载自:http://www.mianhuage.com/752.html 1.安装前准备 1.1.准备安装包generic.jar1.2.创建weblogic用户及用户组创建组命令:groupadd ...
- WIN7系统没有USB驱动和以太网驱动如何操作
| 欢迎关注个人公众号 zclinux_note 第一时间获取关于linux使用的技巧.探索Linux的奥秘 | 今天在单位安装了一台win7纯净版,但是安装完成后发现usb没有反应,插上网 ...
- (四)React Ant Design Pro + .Net5 WebApi:PostgreSQL数据库环境搭建
一.简介 PostgreSQL,开源数据库(没听过小伙伴自己反思一下自行百度) PgAdmin,官方提供的数据库管理工具. 二.环境 1. 官网下载包,安装数据库 tar xjvf /app/pack ...
- python--or 和 and 表达式
or表达式: 两边为一真一假,返回真: 两边都为假,返回右边: 两边都为真,返回左边: and表达式: 两边为一真一假,返回假: 两边都为假,返回左边: 两边都为真,返回右边:
- 运用 pyinstaller 打包的python exe文件运行 去掉命令行窗口及其他参数汇总
运行exe文件的时候,会弹出一个dos命令窗口,这个窗口可以看到一些打印信息,如果想只运行tkinter 页面,去掉dos窗口需要在打包的时候 加上 -w 参数 pyinstaller -F XX.p ...
- jvm源码解析java对象头
认真学习过java的同学应该都知道,java对象由三个部分组成:对象头,实例数据,对齐填充,这三大部分扛起了java的大旗对象,实例数据其实就是我们对象中的数据,对齐填充是由于为了规则分配内存空间,j ...
- 客户端必须在它发送到服务器的所有帧中添加掩码(Mask)
在WebSocket协议中,数据是通过一系列数据帧来进行传输的.为了避免由于网络中介(例如一些拦截代理)或者一些在第10.3节讨论的安全原因,客户端必须在它发送到服务器的所有帧中添加掩码(Mask)( ...
- 键相同,比较两个map中的值是否相同
获取.排序.比较两个Map中相同key对应value值 /** * * @param hashMap 原数据 * @param hashMap2 需要比较的数据 * @return */ privat ...
- LOJ10159旅游规划
题目描述 W 市的交通规划出现了重大问题,市政府下定决心在全市各大交通路口安排疏导员来疏导密集的车流.但由于人员不足,W 市市长决定只在最需要安排人员的路口安排人员. 具体来说,W 市的交通网络十分简 ...
- 利用Javascript制作网页特效(时间特效)
在网页中经常可以看到各种各样的动态时间显示,在网页中合理地使用时间可以增加网页的时效感. 显示当前时间 getHours().getMinutes().getSeconds()分别获得当前小时数.当前 ...