网络流 -- Shooting Contest(二分匹配)
来源:互联网 发布:绝对萌域淘宝店名 编辑:程序博客网 时间:2024/05/04 09:34
Shooting Contest
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 2279 Accepted: 809 Special Judge
Description
Welcome to the Annual Byteland Shooting Contest. Each competitor will shoot to a target which is a rectangular grid. The target consists of r*c squares located in r rows and c columns. The squares are coloured white or black. There are exactly two white squares and r-2 black squares in each column. Rows are consecutively labelled 1,..,r from top to bottom and columns are labelled 1,..,c from left to right. The shooter has c shots.
A volley of c shots is correct if exactly one white square is hit in each column and there is no row without white square being hit. Help the shooter to find a correct volley of hits if such a volley exists.
Example
Consider the following target:
Volley of hits at white squares in rows 2, 3, 1, 4 in consecutive columns 1, 2, 3, 4 is correct.
Write a program that: verifies whether any correct volley of hits exists and if so, finds one of them.
A volley of c shots is correct if exactly one white square is hit in each column and there is no row without white square being hit. Help the shooter to find a correct volley of hits if such a volley exists.
Example
Consider the following target:
Volley of hits at white squares in rows 2, 3, 1, 4 in consecutive columns 1, 2, 3, 4 is correct.
Write a program that: verifies whether any correct volley of hits exists and if so, finds one of them.
Input
The first line of the input contains the number of data blocks x, 1 <= x <= 5. The following lines constitute x blocks. The first block starts in the second line of the input file; each next block starts directly after the previous one.
The first line of each block contains two integers r and c separated by a single space, 2 <= r <= c <= 1000. These are the numbers of rows and columns, respectively. Each of the next c lines in the block contains two integers separated by a single space. The integers in the input line i + 1 in the block, 1 <= i <= c, are labels of rows with white squares in the i-th column.
The first line of each block contains two integers r and c separated by a single space, 2 <= r <= c <= 1000. These are the numbers of rows and columns, respectively. Each of the next c lines in the block contains two integers separated by a single space. The integers in the input line i + 1 in the block, 1 <= i <= c, are labels of rows with white squares in the i-th column.
Output
For the i-th block, 1 <= i <= x, your program should write to the i-th line of the standard output either a sequence of c row labels (separated by single spaces) forming a correct volley of hits at white squares in consecutive columns 1, 2, ..., c, or one word NO if such a volley does not exists.
Sample Input
24 42 43 41 31 45 51 52 43 42 42 3
Sample Output
2 3 1 4NO
Source
CEOI 1997
/*一开始拿到这道题一下子就想到了二分图的最大匹配,然后想来想去没有把图的映射关系想明白,就放弃二分了,转去想DP,但是想来想去也没有找到子结构关系,于是又转回二分图。经过仔细分析终于找到了规律,首先如果列数少于行数是肯定要输出NO的,因为一列只能覆盖一行,所以不能覆盖所有行。接下来就是建图了,以行为左,列为右建立二分图,然后对二分图算最大匹配total,如果total < 行数则输出NO,否则依次遍历所有列并输出其对应的行即pre,对于pre[i] != 0的就输出pre[i]否则,从i可以连的行中随便找一个输出即可*/#include <iostream> #define MAX_N 1000 using namespace std;bool v[MAX_N + 1];int pre[MAX_N + 1];int rowCol[MAX_N + 1][MAX_N + 1];int colRow[MAX_N + 1];int r, c;bool canGo(int from){<span style="white-space:pre"></span>int num = rowCol[from][0];<span style="white-space:pre"></span>int p, to;<span style="white-space:pre"></span>for (p = 1; p <= num; p++)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>to = rowCol[from][p];<span style="white-space:pre"></span>if (!v[to])<span style="white-space:pre"></span>{<span style="white-space:pre"></span>v[to] = true;<span style="white-space:pre"></span>if (pre[to] == 0 || canGo(pre[to]))<span style="white-space:pre"></span>{<span style="white-space:pre"></span>pre[to] = from;<span style="white-space:pre"></span>return true;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>return false;}int main(){<span style="white-space:pre"></span>int caseN, i;<span style="white-space:pre"></span>FILE *file = freopen("in13.txt", "r", stdin);<span style="white-space:pre"></span>if (!file)<span style="white-space:pre"></span>return 1;<span style="white-space:pre"></span>scanf("%d", &caseN);<span style="white-space:pre"></span>while (caseN--)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>int row1, row2;<span style="white-space:pre"></span>memset(rowCol, 0, sizeof(rowCol));<span style="white-space:pre"></span>scanf("%d%d", &r, &c);<span style="white-space:pre"></span>for (i = 1; i <= c; i++)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>scanf("%d%d", &row1, &row2);<span style="white-space:pre"></span>rowCol[row1][0]++;<span style="white-space:pre"></span>rowCol[row1][rowCol[row1][0]] = i;<span style="white-space:pre"></span>colRow[i] = row1;<span style="white-space:pre"></span>rowCol[row2][0]++;<span style="white-space:pre"></span>rowCol[row2][rowCol[row2][0]] = i;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>int total = 0;<span style="white-space:pre"></span>bool can = true;<span style="white-space:pre"></span>if (c < r) can = false;<span style="white-space:pre"></span>else<span style="white-space:pre"></span>{<span style="white-space:pre"></span>memset(pre, 0, sizeof(pre));<span style="white-space:pre"></span>for (i = 1; i <= r; i++)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>memset(v, 0, sizeof(v));<span style="white-space:pre"></span>if (canGo(i)) total++;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>if (total < r) can = false;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>if (!can) printf("NO\n");<span style="white-space:pre"></span>else<span style="white-space:pre"></span>{<span style="white-space:pre"></span>for (i = 1; i <= c; i++)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>if (i != 1) printf(" ");<span style="white-space:pre"></span>if (pre[i] != 0) printf("%d", pre[i]);<span style="white-space:pre"></span>else printf("%d", colRow[i]);<span style="white-space:pre"></span>}<span style="white-space:pre"></span>printf("\n");<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>return 0;}
0 0
- 网络流 -- Shooting Contest(二分匹配)
- poj 1719 Shooting Contest 二分匹配
- [二分匹配]poj 1719 Shooting Contest
- POJ 1719 Shooting Contest 二分匹配
- POJ1719- Shooting Contest(二分图最大匹配)
- POJ 1719 Shooting Contest 二分匹配
- poj 1719 Shooting Contest 二分匹配 匈牙利
- POJ--1719[Shooting Contest] 有源汇上下界可行流或二分匹配
- POJ 1719 Shooting Contest 二分图最大匹配
- POJ 1719 Shooting Contest(二分图匹配)
- POJ - 1719 Shooting Contest 二分图最大匹配
- Shooting Contest(POJ-1719)(二分最大匹配)
- poj 1719 Shooting Contest 二分图匹配的一种特殊情况
- POJ题目1719 Shooting Contest(二分图)
- [网络流] 二分图匹配
- POJ 1719 Shooting Contest
- poj 1719 Shooting Contest
- poj1719 - Shooting Contest
- cocos2dx-v3.0命令行创建工程
- 光流法
- maven如何打包源代码
- 简单库函数的实现
- Quartz Spring 报错!自动注解! Couldn't retrieve trigger: ORA-00942: 表或视图不存在
- 网络流 -- Shooting Contest(二分匹配)
- post===non posted transaction事务类型学习--PCIE学习笔记
- 多播的实现和需要注意的问题
- CentOS下Nexus安装
- Logistic and Softmax Regression (逻辑回归和Softmax回归)
- 【Spark亚太研究院系列丛书】Spark实战高手之路-第3章Spark架构设计与编程模型第1节:为什么Spark是大数据必然的现在和未来?(1)
- 网络编程socket 之TCP三路握手和四路握手
- Zookeeper的安装和配置
- struts zip打包多个文件并下载