• POJ2553 The Bottom of a Graph(强连通分量+缩点)


    题目是问,一个有向图有多少个点v满足∀w∈V:(v→w)⇒(w→v)。

    把图的强连通分量缩点,那么答案显然就是所有出度为0的点。

    用Tarjan找强连通分量:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 #define MAXN 5555
     6 #define MAXM 5555*5555
     7 struct Edge{
     8     int u,v,next;
     9 }edge[MAXM];
    10 int NE,head[MAXN];
    11 void addEdge(int u,int v){
    12     edge[NE].u=u; edge[NE].v=v; edge[NE].next=head[u];
    13     head[u]=NE++;
    14 }
    15 
    16 int bn,belong[MAXN],stack[MAXN],top;
    17 bool instack[MAXN];
    18 int dn,dfn[MAXN],low[MAXN];
    19 void dfs(int u){
    20     dfn[u]=low[u]=++dn;
    21     stack[++top]=u; instack[u]=1;
    22     for(int i=head[u]; i!=-1; i=edge[i].next){
    23         int v=edge[i].v;
    24         if(dfn[v]==0){
    25             dfs(v);
    26             low[u]=min(low[u],low[v]);
    27         }else if(instack[v]){
    28             low[u]=min(low[u],dfn[v]);
    29         }
    30     }
    31     if(dfn[u]==low[u]){
    32         int v; ++bn;
    33         do{
    34             v=stack[top--];
    35             instack[v]=0;
    36             belong[v]=bn;
    37         }while(u!=v);
    38     }
    39 }
    40 
    41 int deg[MAXN];
    42 int main(){
    43     int n,m,a,b;
    44     while(~scanf("%d",&n) && n){
    45         NE=0;
    46         memset(head,-1,sizeof(head));
    47         scanf("%d",&m);
    48         while(m--){
    49             scanf("%d%d",&a,&b);
    50             addEdge(a,b);
    51         }
    52         top=dn=bn=0;
    53         memset(dfn,0,sizeof(dfn));
    54         memset(instack,0,sizeof(instack));
    55         for(int i=1; i<=n; ++i){
    56             if(dfn[i]==0) dfs(i);
    57         }
    58         memset(deg,0,sizeof(deg));
    59         for(int i=0; i<NE; ++i){
    60             int u=belong[edge[i].u],v=belong[edge[i].v];
    61             if(u==v) continue;
    62             ++deg[u];
    63         }
    64         bool first=1;
    65         for(int i=1; i<=n; ++i){
    66             if(deg[belong[i]]==0){
    67                 if(first) first=0;
    68                 else putchar(' ');
    69                 printf("%d",i);
    70             }
    71         }
    72         putchar('
    ');
    73     }
    74     return 0;
    75 } 
  • 相关阅读:
    你写的单例真的安全吗?
    CountDownLatch&&CyclicBarrier
    初步认识AQS
    Atomic底层原理
    volatile关键字
    Linux常用服务类相关命令
    线程池
    由浅入深TheradLocal
    synchronized关键字
    .net 中dapper实现事务的三种方式总结
  • 原文地址:https://www.cnblogs.com/WABoss/p/5156859.html
Copyright © 2020-2023  润新知