zoukankan      html  css  js  c++  java
  • hdu 4324 拓扑排序

    题意:给出一堆人的喜爱关系,判断有没有三角恋-_-||

    其实就是判断是否存在三条边的环。

    一开始我是这么想的:

    先拓扑排序,如果没有环那就直接No
    如果有环?挑出环里的任意一个点(拓扑排序结束后不在拓扑序里面的点就在环里),然后从这个点开始dfs,看三步之后能不能回到这个点。(可以证明,只要考察一个点就行)

    然而TLE了= =

    其实仔细想想可以发现,后面那个dfs没有必要。

    注意一个细节:A[i][j]<>A[j][i]。也就是说若i到j不通,那么j到i一定通

    可以证明,若这样的图中存在环,那么一定存在三角环(证明Reference:http://blog.csdn.net/xiaofengcanyuexj/article/details/29179639)

    数据不大,邻接矩阵就ok

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 #define MAXN 2100
     6 
     7 int a[MAXN][MAXN];
     8 int d[MAXN];
     9 bool ok;
    10 int N,T,x,y;
    11 
    12 void topsort()
    13 {
    14     bool circle=false;
    15     int i=0;
    16     while(i<N)
    17     {
    18         int j=1;
    19         while(d[j]!=0)  j++;
    20         if(j==N+1)
    21         {
    22             circle=true;
    23             break;
    24         }
    25         d[j]=-1;
    26         for(int k=1;k<=N;k++)
    27             if(a[j][k]==1)
    28             {
    29                 d[k]--;
    30                 a[j][k]=0;
    31             }
    32         i++;
    33     }
    34     if((circle)&&(N>=3))
    35         cout<<"Yes"<<endl;
    36     else
    37         cout<<"No"<<endl;
    38 }
    39 
    40 int main()
    41 {
    42     cin>>T;
    43     for(int Times=1;Times<=T;Times++)
    44     {
    45         cin>>N;
    46         memset(d,0,sizeof(d));
    47         memset(a,0,sizeof(a));
    48         char ch[2010];
    49         for(int i=1; i<=N; i++)
    50         {
    51             scanf("%s",ch);
    52             for(int j=1;j<=N;j++)
    53             {
    54                 if (ch[j-1]=='1')
    55                 {
    56                     d[j]++;
    57                     a[i][j]=1;
    58                 }
    59             }
    60         }
    61         cout<<"Case #"<<Times<<": ";
    62         topsort();
    63 
    64     }
    65     return 0;
    66 }
    View Code

    顺便记两个拓扑排序模板:

    邻接矩阵:见本题

    邻接表:

     1 邻接表建图: 
     2  32 void addedge(int x,int y)       //x->y
     3  33 {
     4  34     d[y]++;             //d[i]:点i的入度
     5  35     ev[cnt]=y;          //ev[i]:第i条边的destination
     6  36     nxt[cnt]=head[x];   //nxt[i]:第i条边的下一条边
     7  37     head[x]=cnt;        //head[i]:由i节点出发的第一条边的序号
     8  38     cnt++;
     9  39 }
    10 
    11 --------------------------------------------------------------------------------
    12 
    13 void topsort()
    14 {
    15     vector<int> vec;
    16     for(int i=1; i<=N; i++)
    17         if(d[i]==0)     vec.push_back(i);
    18     for(int i=0; i<vec.size(); i++)
    19     {
    20         int x=vec[i];
    21         for(int j=head[x]; j!=0; j=nxt[j])
    22         {
    23             int y=ev[j];
    24             d[y]--;
    25             if(d[y]==0)     vec.push_back(y);
    26         }
    27     }
    28     int last=vec.size();
    29     //last!=N说明有环
    30 }
    31 如果嫌慢可以把vector改写成普通数组
    View Code

    //PS:Reference的那个博主是地大的本科生,本科毕业就拿到了人人+去哪儿offer,orz

  • 相关阅读:
    20181120-1 每周例行报告
    20181113-2 每周例行报告
    20181030-4 每周例行报告
    20181023-3 每周例行报告
    第六周例行报告
    软件功能说明书final修订
    第十二周——例行报告
    PSP总结报告
    第十一周——例行报告
    PSP Daily软件beta版本——基于NABCD评论,及改进建议
  • 原文地址:https://www.cnblogs.com/pdev/p/4505945.html
Copyright © 2011-2022 走看看