• hdu3594 强连通(仙人掌图)


    题意:给定一张有向图,问是否是仙人掌图。仙人掌图的定义是,首先,这张图是一个强连通分量,其次所有边在且仅在一个环内。

    首先,tarjan可以判强连通分量是否只有一个。然后对于所有边是否仅在一个环内,我的做法是,当一个点在 tarjan 的 dfs 中,引出下一条边,如果这条边指向了一个时间轴上比它大的点,那么该点一定是 dfs 树中它的后继节点,在之前必定有一条这两点之间的路径,那么这两点之间就已经有两条路径了,而从后继节点一定能返回到祖先节点而形成环(强连通),所以返回祖先节点的路径一定与两点间的两条路径形成两个环,就不符合仙人掌图了。而如果这条边指向了一个时间轴上比它小的点,那么或者那个点是这个圈的访问祖先,或者那个点是其他圈中的点,那么这一段一定都在一个圈上,那就不断遍历回祖先将点的访问数+1。最后再判断是否每个点的访问数小于等于1就行了。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stack>
     4 #include<queue>
     5 using namespace std;
     6 
     7 const int maxn=2e4+5;
     8 const int maxm=5e4+5;
     9 
    10 int head[maxn],point[maxm],nxt[maxm],size;
    11 int n,t,scccnt;
    12 int stx[maxn],low[maxn],scc[maxn];
    13 int fa[maxn];
    14 int vis[maxn];
    15 stack<int>S;
    16 bool f;
    17 
    18 void init(){
    19     memset(head,-1,sizeof(head));
    20     size=0;
    21     f=1;
    22     memset(vis,0,sizeof(vis));
    23     memset(fa,-1,sizeof(fa));
    24 }
    25 
    26 void add(int a,int b){
    27     point[size]=b;
    28     nxt[size]=head[a];
    29     head[a]=size++;
    30 }
    31 
    32 void dfs(int s,int pre){
    33     fa[s]=pre;
    34     stx[s]=low[s]=++t;
    35     S.push(s);
    36     for(int i=head[s];~i;i=nxt[i]){
    37         int j=point[i];
    38         if(!stx[j]){
    39             dfs(j,s);
    40             low[s]=min(low[s],low[j]);
    41         }
    42         else if(!scc[j]){
    43             if(stx[j]<stx[s]){
    44                 int k=s;
    45                 while(k!=j&&k!=-1){
    46                     vis[k]++;
    47                     k=fa[k];
    48                 }
    49             }
    50             else f=0;
    51             low[s]=min(low[s],stx[j]);
    52         }
    53     }
    54     if(low[s]==stx[s]){
    55         scccnt++;
    56         while(1){
    57             int u=S.top();S.pop();
    58             scc[u]=scccnt;
    59             if(s==u)break;
    60         }
    61     }
    62 }
    63 
    64 void setscc(){
    65     memset(stx,0,sizeof(stx));
    66     memset(scc,0,sizeof(scc));
    67     t=scccnt=0;
    68     for(int i=0;i<n;++i)if(!stx[i])dfs(i,-1);
    69 }
    70 
    71 int main(){
    72     int T;
    73     scanf("%d",&T);
    74     while(T--){
    75         int m;
    76         scanf("%d",&n);
    77         init();
    78         int a,b;
    79         while(scanf("%d%d",&a,&b)&&a+b){
    80             add(a,b);
    81         }
    82         setscc();
    83         for(int i=0;i<n;++i)if(vis[i]>1)f=0;
    84         if(scccnt>1||!f)printf("NO
    ");
    85         else printf("YES
    ");
    86     }
    87     return 0;
    88 }
    View Code
  • 相关阅读:
    注册时按钮上的时间倒计时
    不能修改/删除/添加数据.(NTFS问题)
    站在2009年的门槛上
    超强PHP分页类(转自PHPCHINA)
    System.Web.Caching.Cache类 缓存 各种缓存依赖
    Wxpython快速构建GUI窗口程序
    Python2 和 Python3 有哪些差别
    12306数据库遭泄露,请尽快修改密码
    王欣复出后的第一款产品
    在命令行打开安卓UI界面
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4814504.html
Copyright © 2020-2023  润新知