zoukankan      html  css  js  c++  java
  • HDU 2094 产生冠军 dfs加map容器

    解题报告:有一群人在打乒乓球比赛,需要在这一群人里面选出一个冠军,现在规定,若a赢了b,b又赢了c那么如果a与c没有比赛的话,就默认a赢了c,而如果c赢了a的话,则这三个人里面选不出冠军,还有就是如果一个人没有输给别人,但是存在一个人跟这个人之间的输赢关系不能确定的话,也是作为选不出冠军的情况,现在输入一群人的比赛情况,要你确定,利用这组比赛情况能不能确定一个冠军,能的话输出Yes,否则输出No。

    感觉这题应该有很多种不同的解法,其中由于输入的是选手的名字,所以还要用到map容器。我的做法是枚举每一个人是否有可能是冠军,即从这个人开始出发,用dfs搜索,看这个人一共赢了多少个人,然后他赢的人的个数是否是总的比赛的人数M-1,如果是,则说明他就是冠军,如果枚举每一个人都不满足的话,则说明没有冠军。要注意的是,

    这样做有很多情况可以减掉,第一,如果某个人;有过输给别人的记录,则这个人可以直接跳过,不需要看他赢了多少人,这样可以减掉一大部分,然后每次已经搜过的要标记掉,即已经被人打败过的要标记掉,要不然如果两个人都同时赢了同一个人的话,则这个人将会被统计两次。代码贴上:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<map>
     4 #include<iostream>
     5 #include<string>
     6 #include<cstring>
     7 using namespace std;
     8 
     9 const int maxn = 2000+3;
    10 int M,num;
    11 bool map2[maxn][maxn],mark[maxn];
    12 map<string,int> mp1;
    13 pair<map<string,int>::iterator,bool> iter;
    14 int visit[maxn];
    15 int find(const char *s) {
    16     string s1 = s;
    17     iter = mp1.insert(pair<string,int> (s1,++M));
    18     if(iter.second)
    19     return M;
    20     else {
    21         M--;
    22         return mp1[s1];
    23     }
    24 }
    25 void dfs(int x) {
    26     for(int i = 1;i<=M;++i)
    27     if(!mark[i] && map2[x][i]) {
    28         num++;
    29         mark[i] = 1;
    30         dfs(i);
    31     }
    32 }
    33 int main() {
    34     int n;
    35     char str1[100],str2[100];
    36     while(scanf("%d",&n),n) {
    37         M = 0;
    38         memset(map2,0,sizeof(map2));
    39         memset(visit,0,sizeof(visit));
    40         for(int i = 1;i<=n;++i) {
    41             scanf("%s%s",str1,str2);
    42             int x = find(str1);
    43             int y = find(str2);
    44             map2[x][y] = 1;
    45             visit[y] = 1;
    46         }
    47         bool flag = 0;
    48         for(int i = 1;i<=M;++i)
    49         if(!visit[i]) {
    50             num = 0;
    51             memset(mark,0,sizeof(mark));
    52             mark[i] = 1;
    53             dfs(i);
    54             if(num == M-1) {
    55                 flag = 1;
    56                 break;
    57             }
    58         }
    59         printf(flag? "Yes
    ":"No
    ");
    60         mp1.clear(); 
    61     }
    62     return 0;
    63 }    
    View Code
  • 相关阅读:
    luogu P3238 [HNOI2014]道路堵塞
    luogu P3235 [HNOI2014]江南乐
    luogu P3237 [HNOI2014]米特运输
    luogu P3233 [HNOI2014]世界树
    luogu P3234 [HNOI2014]抄卡组
    luogu P3250 [HNOI2016]网络
    luogu P3201 [HNOI2009]梦幻布丁
    luogu P4148 简单题
    luogu P3767 膜法
    luogu P4314 CPU监控
  • 原文地址:https://www.cnblogs.com/xiaxiaosheng/p/3255226.html
Copyright © 2011-2022 走看看