poj2186tarjan演算法縮點求出度

來源:互聯網
上載者:User

標籤:return   就是   cst   入門   題目   傳遞   out   集合   node   

poj2186tarjan演算法縮點求出度

自己打一遍第一題,入門啦,入門啦

題目還算簡單,多頭牛,給你仰慕關係(可傳遞),問你最後有沒有牛被所有的牛仰慕

根據關係可以建圖,利用tarjan演算法縮點處理後,得到有向非循環圖,縮成的點都是相互仰慕的,所以根據傳遞性也就是可以看成一個點了,然後染色分塊,計算每一塊的出度。

如果出度為0有且僅有一個,那麼輸出該塊內所有的點,都符合要求

如果有多個直接輸出0即可

#include <iostream>#include <cstdio>#include <string.h>using namespace std;const int maxn = 10005;const int maxm = 100005;struct node{    int to,pre;}e[maxm];int n,m;int idx;int id[maxn],cnt;int dfn[maxn],low[maxn];int stack1[maxn],s_top;int out[maxn];int color[maxn];int vis[maxn];int cut_point = 0;void init(){    memset(dfn,0,sizeof(dfn));    memset(vis,0,sizeof(vis));    memset(color,0,sizeof(color));    memset(low,0,sizeof(low));    memset(id,-1,sizeof(id));    memset(out,0,sizeof(id));    cnt = 0;    idx = 0;    s_top = 0;    cut_point = 0;}void add(int u,int v){    e[cnt].to = v;    e[cnt].pre = id[u];    id[u] = cnt++;}void tarjan(int u, int pre){    dfn[u] = low[u] = ++idx;    vis[u] = 1;    stack1[s_top++] = u;    for(int i = id[u];~i;i = e[i].pre)    {        int v = e[i].to;        if(!vis[v])        {            tarjan(v,u);            low[u] = min(low[v],low[u]);        }        else        {            low[u] = min(low[u],dfn[v]);        }    }    if(low[u] == dfn[u])    {        cut_point++;//顏色1 。。。n        while(s_top > 0 && stack1[s_top] != u)//目的是先處理完元素在判斷是不是最後一個        {            s_top--;            vis[stack1[s_top]] = 2;            color[stack1[s_top]] = cut_point;        }    }}int main(){    int u,v;    while(~scanf("%d%d",&n,&m))    {        //初始化        init();        //添加邊        for(int i = 0;i < m;i++)        {            scanf("%d%d",&u,&v);            add(u,v);        }        //縮點處理——染色        for(int i = 1;i <= n;i++)//防止不連通的情況        {            if(!vis[i])            {                tarjan(i,-1);            }        }        //染色成功後,記錄出度        for(int i = 1;i <= n;i++)        {            for(int j = id[i];~j;j = e[j].pre)            {                int v = e[j].to;                if(color[i] != color[v])                {                    ++out[color[i]];                }            }        }        //看看度為0的點的集合,找出所有的點        //color還要一樣,不能有兩個        int sum = 0,p_color;        for(int i = 1;i <= cut_point;i++)        {            if(!out[i])                sum++,p_color = i;        }        if(sum == 1)        {            int ans = 0;            for(int i = 1;i <= n;i++)            {                if(color[i] == p_color)ans++;            }            printf("%d\n",ans);        }        else        {            puts("0");        }    }    return 0;}

 

poj2186tarjan演算法縮點求出度

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.