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.
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
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\n",p[m][0]); 57 else printf("%d\n",prt[m]); 58 }else puts("NO"); 59 } 60 return 0; 61 }