poj 1719 Shooting Contest (二分匹配)

Shooting Contest
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 3812   Accepted: 1389   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.

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. 

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

2
4 4
2 4
3 4
1 3
1 4
5 5
1 5
2 4
3 4
2 4
2 3

Sample Output

2 3 1 4
NO

Source

 
    开始没弄清楚题意,WA了两次,题意是给出一个n*m的矩形,每一列有两格是白色的,要求匹配出每列一个,每行至少一个的匹配。不行输出NO。
    先正常进行最大匹配,输出结果时把没匹配到的列随便分配两个中的一个即可。
 1 //220K    110MS    C++    1341B    2014-06-03 15:44:38
 2 //每列一个,每行至少一个 
 3 #include<iostream>
 4 #include<vector>
 5 #define N 1005
 6 using namespace std;
 7 vector<int>V[N];
 8 int vis[N];
 9 int match[N];
10 int p[N][2];
11 int n,m;
12 int dfs(int u)
13 {
14     for(int i=0;i<V[u].size();i++){
15         int v=V[u][i];
16         if(!vis[v]){
17             vis[v]=1;
18             if(match[v]==-1 || dfs(match[v])){
19                 match[v]=u;
20                 return 1;
21             }
22         }
23     }
24     return 0;
25 }
26 int hungary()
27 {
28     memset(match,-1,sizeof(match));
29     int ret=0;
30     for(int i=1;i<=m;i++){
31         memset(vis,0,sizeof(vis));
32         ret+=dfs(i);
33     }
34     return ret;
35 }
36 int main(void)
37 {
38     int t;
39     scanf("%d",&t);
40     while(t--)
41     {
42         scanf("%d%d",&n,&m);
43         for(int i=0;i<=m;i++) V[i].clear();
44         for(int i=1;i<=m;i++){
45             scanf("%d%d",&p[i][0],&p[i][1]);
46             V[i].push_back(p[i][0]);
47             V[i].push_back(p[i][1]);
48         }
49         int prt[N]={0};
50         if(hungary()==n){
51             for(int i=1;i<=n;i++)
52                 prt[match[i]]=i;
53             for(int i=1;i<m;i++)
54                 if(prt[i]==0) printf("%d ",p[i][0]);
55                 else printf("%d ",prt[i]);
56             if(prt[m]==0) printf("%d
",p[m][0]); 
57             else printf("%d
",prt[m]);
58         }else puts("NO");
59     }
60     return 0;
61 }
 
原文地址:https://www.cnblogs.com/GO-NO-1/p/3765905.html