Shooting Contest - 北电1719(二分匹配)

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
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 1005
int row;
int column;
bool state[N][N];
int pai[N];
bool color[N];
bool fine(int k){
	int i;
	bool t;
	for(i=1;i<=column;i++){
		if(state[k][i]&&!color[i]){
			color[i]=true;
			if(!pai[i]||fine(pai[i])){
				pai[i]=k;
				return true;
			}
		}
	}
	return false;
}
int main(){
	int i,j,k,n,p,q,V;
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%d%d",&row,&column);
		memset(state,false,sizeof(state));
		for(j=1;j<=column;j++){
			scanf("%d%d",&p,&q);
			state[p][j]=true;
			state[q][j]=true;
		}
		V=0;
		memset(pai,0,sizeof(pai));
		for(j=1;j<=row;j++){//对于每一行,找出一个
			memset(color,false,sizeof(color));
			if(fine(j))
				V++;
		}
		if(V==row){//如果每一行均能找出 
			for(j=1;j<=column;j++){//对于被找到的列,输出其被找到的行数,
				if(pai[j]!=0){
					printf("%d",pai[j]);
					if(j!=column)
						printf(" ");
				}
				else//对于没被找到的列,输出该列第一个白色块
					for(k=1;k<=row;k++)
						if(state[k][j]){
							printf("%d",k);
							if(j!=column)
								printf(" ");
							break;
						}
			}
			printf("\n");
		}
		else//否则,输出NO 
			printf("NO\n");
	}	
	return 0;
}

  

posted @ 2011-08-10 17:18  kahreman  阅读(226)  评论(0编辑  收藏  举报