poj 2762 Going from u to v or from v to u? (判斷是否是弱聯通圖)

來源:互聯網
上載者:User

標籤:blog   os   2014   for   io   演算法   

題意:給定一個有向圖有m條單向邊,判斷是否任意兩點都可達(a能到b或者b能到a或者互相可達),即求

            弱聯通分量。


演算法:

先縮點求強連通分量。然後重建立圖,判斷新圖是否是一條單鏈,即不能分叉,如果分叉了就會存在不可達的情況。

怎麼判斷是否是單鏈呢?

就是每次入度為0的點都只有一個,即每次隊列裡只有一個點。


(    o(╯□╰)o。。。。。好像已經是第二次用pair記錄原圖的點對,然後存pair的vector忘記清空導致wa來wa去! )


#include<cstdio>#include<iostream>#include<cstring>#include<queue>#include<vector>#define maxn 1010#define maxm 20010using namespace std;struct node{    int to,next;}edge[maxm],edge2[maxm];int head[maxn],cnt,n;int clk,top,s[maxn],scc,dfn[maxn],low[maxn],belong[maxn];bool instack[maxn],vis[maxn];int head2[maxn],cnt2,in[maxn];typedef pair<int,int> PII;vector<PII> xx;queue<int> q;void add(int x,int y){    edge[cnt].to = y;    edge[cnt].next = head[x];    head[x] = cnt++;}void add2(int x,int y){    edge2[cnt2].to = y;    edge2[cnt2].next = head2[x];    head2[x] = cnt2++;}void dfs(int x){    dfn[x] = low[x] = clk++;    s[top++] = x;    instack[x] = true;    for(int i=head[x];i!=-1;i = edge[i].next)    {        int u = edge[i].to;        if(dfn[u]==-1)        {            dfs(u);            low[x] = min(low[u],low[x]);        }        else if(instack[u])        {            low[x] = min(low[x],dfn[u]);        }    }    if(low[x]==dfn[x])    {        int u;        scc++;        do        {            u = s[--top];            instack[u]=false;            belong[u] = scc;        }while(u!=x);    }}void tarjan(){    memset(dfn,-1,sizeof(dfn));    memset(instack,0,sizeof(instack));    memset(belong,0,sizeof(belong));    clk = top = scc = 0;    for(int i=1;i<=n;i++)    {        if(dfn[i]==-1)            dfs(i);    }}bool topo(){    memset(vis,0,sizeof(vis));    int c = 0;    while(!q.empty())        q.pop();    for(int i=1;i<=scc;i++)    {        if(!in[i])        {            c++;            q.push(i);        }    }    if(c>1) return false;    while(!q.empty())    {        int u = q.front();        q.pop();        if(vis[u]) continue;        vis[u] = true;        c = 0;        for(int i=head2[u];i!=-1;i=edge2[i].next)        {            int v = edge2[i].to;            in[v]--;            if(!in[v])            {                q.push(v);                c++;            }        }        if(c>1)            return false;    }    return true;}int main(){    int m,a,b,T;    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&m);        memset(head,-1,sizeof(head));        memset(in,0,sizeof(in));        xx.clear();        cnt = 0;        for(int i=1;i<=m;i++)        {            scanf("%d%d",&a,&b);            add(a,b);            xx.push_back(make_pair(a,b));        }        tarjan();        memset(head2,-1,sizeof(head2));        cnt2 = 0;        for(int i=0;i<xx.size();i++)        {            int u = xx[i].first,v = xx[i].second;            if(belong[u]!=belong[v])            {                add2(belong[u],belong[v]);                in[belong[v]]++;            }        }        if(topo()) printf("Yes\n");        else printf("No\n");    }    return 0;}




聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.