csuoj 集训队分组

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;
}
原文地址:https://www.cnblogs.com/tracy520/p/6974520.html