zoukankan      html  css  js  c++  java
  • CSUOJ 1081 集训队分组

    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

    建有向图,对每个结点bfs一遍,找出从它出发可以到达多少个结点,如果有n-k个结点在它之后,那它就是前k个了;

    邻接矩阵会超时,要使用邻接表;

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<vector>
     4 #define N 1005
     5 using namespace std;
     6 
     7 vector<int> g[N];
     8 char vis[N];
     9 
    10 int bfs(int u)
    11 {
    12     int cx, nx, ret = 0;
    13     int Q[N], front, rear;
    14 
    15     memset(vis, 0, sizeof(vis));
    16     Q[1] = u;
    17     vis[u] = 1;
    18     front = 1;
    19     rear  = 2;
    20     while(front < rear){
    21         cx = Q[front++];
    22         for(int i = 0; i < g[cx].size(); i++){
    23             nx = g[cx][i];
    24             if (!vis[nx]){
    25                 Q[rear++] = nx;
    26                 vis[nx] = 1;
    27                 ret++;
    28             }
    29         }
    30     }
    31     return ret;
    32 }
    33 
    34 int main()
    35 {
    36     int n, k, m;
    37     while(scanf("%d %d %d", &n, &k, &m) != EOF){
    38         int u, v;
    39         for(int i = 1; i <= n; i++)
    40             g[i].clear();
    41         for (int i = 0; i < m; i++){
    42             scanf("%d%d", &u, &v);
    43             g[u].push_back(v);
    44         }
    45         int cnt = 0;
    46         for(int i = 1; i <= n; i++){
    47             if(bfs(i) >= n-k)
    48                 cnt++;
    49             if(cnt >= k)
    50                 break;
    51         }
    52         if(cnt >= k)
    53             printf("YES
    ");
    54         else
    55             printf("NO
    ");
    56     }
    57     return 0;
    58 }

    PS:参考的大牛的博客,没看太懂……



  • 相关阅读:
    Java 简单算法--打印乘法口诀(只使用一次循环)
    Java简单算法--求100以内素数
    ubuntu 16.04 chrome flash player 过期
    java 网络API访问 web 站点
    java scoket (UDP通信模型)简易聊天室
    leetcode1105 Filling Bookcase Shelves
    leetcode1140 Stone Game II
    leetcode1186 Maximum Subarray Sum with One Deletion
    leetcode31 Next Permutation
    leetcode834 Sum of Distances in Tree
  • 原文地址:https://www.cnblogs.com/zzy9669/p/3876001.html
Copyright © 2011-2022 走看看