杭電2094はチャンピオンを生んだ【トポロジーランキング】

2207 ワード

優勝が決まる
Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11580    Accepted Submission(s): 5370
Problem Description
一群の人がいて、卓球の試合をして、2対2で引き裂いて、2人の間で最大1試合をします.
試合のルールは以下の通りです.
AがBを負かし、BがCを負かし、AとCの間で試合をしたことがなければ、Aは必ずCを負かすことができると認定する.
AがBを破り、BがCを破り、CがAを負かすと、A、B、Cの3者が優勝することはできない.
このルールによっては、ラウンドをしなくても優勝が決まるかもしれない.あなたの任務は試合の選手たちに直面して、いくつかの試合を経て引き裂かれた後、実際にチャンピオンが生まれたかどうかを確定することです.
 
 
Input
入力にはいくつかの選手群が含まれており、各選手は1つの整数n(n<1000)で始まり、後にn対の選手との試合結果を入力し、試合結果は1対の選手名(真ん中にスペースを隔てて)で表され、前者は後者に勝った.nが0の場合、入力が終了します.
 
 
Output
各選手群について、優勝者が生まれたと判断した場合は、1行に「Yes」を出力し、そうでなければ1行に「No」を出力します.
 
 
Sample Input

   
   
   
   
3 Alice Bob Smith John Alice Smith 5 a c c d d e b e a d 0

 
 
Sample Output

   
   
   
   
Yes No

 
まあまあですが、記憶が面倒なので、同じ選手を排除しなければなりません.
 
#include<stdio.h>
#include<string.h>
char win[1010][1010], lose[1010][1010];
int indegree[1010];

void topo(int n){
	int i, j, cnt = 0;
	memset(indegree, 0, sizeof(indegree));
	for(i = 0; i < n; ++i){
		for(j = 0; j < n; ++j){
			if(strcmp(win[i], lose[j]) == 0){
			indegree[i] = 1;	
			}
			if(!indegree[i] && !indegree[j] && i < j){
				if(strcmp(win[i], win[j]) == 0)
				indegree[j] = 1;
			}
		}
	}
	for(i = 0; i < n; ++i){
		if(!indegree[i])
		cnt++;
	}
	if(cnt == 1) printf("Yes
"); else printf("No
"); } int main(){ int n; while(~scanf("%d", &n), n){ int i; for(i = 0; i < n; ++i){ scanf("%s%s", win[i], lose[i]); } topo(n); } return 0; }