zoukankan      html  css  js  c++  java
  • poj2553 有向图缩点,强连通分量。

    //求这样的sink点:它能达到的点,那个点必能达到他,即(G)={v∈V|任意w∈V:(v→w)推出(w→v)}
    //我法:tarjan缩点后,遍历点,如果该点到达的点不在同一个强连通中,该点排除,而且该点所在的
    //的强连通分支所有点都排除(开始因为这个跪WA!慎思!)
    #include<iostream>   //143MS,
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<stack>
    #include<queue>
    using namespace std;
    int n;int m;
    const int MAX=5001;
    vector<vector<int> >edges(MAX);
    int visited[MAX];
    int low[MAX];
    int dfn[MAX];
    int is_sink[MAX];          //统计出入度
    int Strongly_connected_branch[MAX];  //并为一个强连通,标记为1.2.3...
    int num;int times;
    bool is_sink_all[MAX];
    stack<int>s;
    bool instack[MAX];
    void tarjan(int u)
    {
        low[u]=dfn[u]=times++;
        instack[u]=1;
        s.push(u);
        int len=edges[u].size();
        for(int i=0;i<len;i++)
        {
            int v=edges[u][i];
            if(visited[v]==0)          //小心细节!
            {
                 visited[v]=1;
                   tarjan(v);
                if(low[u]>low[v])low[u]=low[v];
            }
            else if(instack[v]&&low[u]>dfn[v])     //有向图,要问是否在栈中,后向边,V为U某个祖先
            {
                low[u]=dfn[v];
            }
        }
        if(dfn[u]==low[u])         //在一个SCC
        {
            num++;int temp;
             do
            {
                 temp=s.top();
                 instack[temp]=0;
                s.pop();
                Strongly_connected_branch[temp]=num;
            } while(temp!=u);
        }
    }
    void initialize()
    {
        num=times=0;
        for(int i=0;i<=n;i++)
        {
            instack[i]=low[i]=dfn[i]=visited[i]=0;
            edges[i].clear();
            is_sink_all[i]=is_sink[i]=1;
            Strongly_connected_branch[i]=-1;
        }
    }
    bool readin()
    {
        scanf("%d",&n);
        if(n==0)return 0;
        scanf("%d",&m);
        initialize();
        int from,to;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&from,&to);
            edges[from].push_back(to);
        }
        return 1;
    }
    void solve()
    {
        for(int i=1;i<=n;i++)
           if(visited[i]==0)
            {
                visited[i]=1;
                tarjan(i);
            }
         for(int i=1;i<=n;i++)     //自己思得:枚举所有边,缩点只是把所有SCC分开
       {                           
          int len=edges[i].size();
           for(int j=0;j<len;j++)
           {
              int v=edges[i][j];
              if(Strongly_connected_branch[v]!=Strongly_connected_branch[i])//b不再用一个强连通分支
              {
                is_sink[i]=0;          
                is_sink_all[Strongly_connected_branch[i]]=0; //其所在强连通全跪!
                break;
              }
           }
        }
        queue<int>q;       //要按顺序输出,无奈。
        for(int i=1;i<=n;i++)
        {
           if(is_sink_all[Strongly_connected_branch[i]]==0){continue;}
           if(is_sink[i]==1)q.push(i);
        }
        while(!q.empty())
        {
            int cur=q.front();
            if(q.size()==1)printf("%d
    ",cur);
            else printf("%d ",cur);
            q.pop();
        }
    }
    int main()            //代码越来越清楚O(∩_∩)O~
    {
       while(readin())
       {
           solve();
       }
       return 0;
    }
    
    

  • 相关阅读:
    The Quad
    将OrCAD Capture CIS的设计文件(.dsn)导入到PADS Logic VX.2.3
    OrCAD Capture CIS 16.6 将版本16.6的设计文件另存为版本16.2的设计文件
    Eclipse IDE 添加jar包到Java工程中
    PADS Logic VX.2.3 修改软件界面语言
    切换Allegro PCB Editor
    Allegro PCB Design GXL (legacy) 将brd文件另存为低版本文件
    Allegro PCB Design GXL (legacy) 设置自动保存brd文件
    Could not create an acl object: Role '16'
    windows 下apache开启FastCGI
  • 原文地址:https://www.cnblogs.com/yezekun/p/3925815.html
Copyright © 2011-2022 走看看