Description
中南大学ACM的暑期集训马上就要开始了,这次集训会将全体N名集训队员(编号分别为1, 2, …, N)按集训选拔赛的排名分成两组,前K名队员分入A组,其余队员分入B组。
但现在助理教练CSGrandeur一不小心把集训选拔赛的排名弄丢了,而之前又没将A组和B组的人员确定出来,于是CSGrandeur打算问一下集训人员他们的名次各是怎样的,以此来确定一下A组的队员。
然而集训队员们都视名次如粪土,只是隐约记得某些人排在了自己的后面,最终反馈到CSGrandeur这里的一共有M条信息,每条信息都可以用一个二元组(x, y) (x!=y)表示,含义为第x名队员记得第y名队员的排名比自己的要靠后。
现在CSGrandeur想知道,根据这M条信息,是否可以确定出A组的队员呢?(默认所有集训队员反映的信息都是符合事实的。)
Input
输入包含多组测试数据。
对于每组测试数据,第一行包含三个正整数N (2<=N<=1000)、K (1<=K<=N)、M (1<=M<=10000),含义同上。接下来M行每行有两个正整数x、y (1<=x, y<=N且x!=y),分别描述了M条信息,对于每对x、y,均表示第x名队员记得第y名队员的排名比自己的要靠后。
Output
对于每组测试数据,如果可以确定出A组的队员,输出“YES”(不包括引号),否则输出“NO”(不包括引号)。
Sample Input
3 1 2 1 2 1 3 3 2 2 1 2 1 3
Sample Output
YES NO
代码:
#include<iostream> #include<set> using namespace std; int rel[1001][1001]; int main(){ int n,m,k; while(cin >> n >> k >> m){ for(int i = 1;i <= 1000;i++){ for(int j = 1;j <= 1000;j++) rel[i][j] = 0; } for(int i = 0;i < m;i++){ int x,y; cin >> x >> y; if(rel[x][y] == 0){ int big[1000]; int bigCnt = 1; big[0] = x; for(int i = 1;i <= n;i++){ if(rel[i][x] == 1){ big[bigCnt++] = i; } } set<int> s; s.insert(y); for(int i = 1;i <= n;i++){ if(rel[y][i] == 1){ s.insert(i); } } for(int i = 0;i < bigCnt;i++){ for(set<int>::iterator it = s.begin();it != s.end();it++){ rel[big[i]][*it] = 1; } } } } int ans = 0; for(int i = 1;i <= n;i++){ int cnt = 0; for(int j = 1;j <= n;j++){ if(rel[i][j] == 1) cnt++; } if(cnt >= n - k) ans++; if(ans >= k) break; } if(ans >= k) cout << "YES" << endl; else cout << "NO" << endl; } return 0; }