poj2553 – The Bottom of a Graph

來源:互聯網
上載者:User

                                
想看更多的解題報告:http://blog.csdn.net/wangjian8006/article/details/7870410
                                  轉載請註明出處:http://blog.csdn.net/wangjian8006

題目大意:如果v點能夠到的點,反過來能夠到達v點,則稱這個點為sink點,輸出所有的sink點
解題思路:求連通分量,然後出度為0的連通分量裡面的點就是sink點

 

/*kosarajuMemory 524KTime   63MS*/#include <iostream>using namespace std;#define MAXM 50010#define MAXV 5010#define min(a,b) (a>b?b:a)typedef struct{int s,t,next,next2;}Edge;Edge edge[MAXM];int n,m,headlist[MAXV],headlist2[MAXV];int order[MAXV],belong[MAXV];int num,count;bool vis[MAXV];void dfs(int x){int i,a;vis[x]=1;for(i=headlist[x];i!=-1;i=edge[i].next){a=edge[i].t;if(!vis[a]) dfs(a);}order[++num]=x;}void dfst(int x){int i,a;belong[x]=count;//記錄結點屬於哪個連通分量vis[x]=1;for(i=headlist2[x];i!=-1;i=edge[i].next2){//要將邊反過來遍曆一遍a=edge[i].s;if(!vis[a]) dfst(a);}}void kosaraju(){int i;memset(vis,0,sizeof(vis));num=count=0;for(i=1;i<=n;i++)if(!vis[i]) dfs(i);memset(vis,0,sizeof(vis));for(i=n;i>=1;i--)if(!vis[order[i]]){count++;dfst(order[i]);}}void output(){int i,j,outdegree[MAXV]={0};for(i=1;i<=n;i++)for(j=headlist[i];j!=-1;j=edge[j].next)if(belong[i]!=belong[edge[j].t]){outdegree[belong[i]]++;}memset(vis,0,sizeof(vis));for(i=1;i<=n;i++)if(!outdegree[belong[i]]) vis[i]=1;for(i=1;i<=n;i++)if(vis[i]) printf("%d ",i);printf("\n");}int main(){int i,a,b;while(scanf("%d",&n) && n){memset(headlist,-1,sizeof(headlist));memset(headlist2,-1,sizeof(headlist2));scanf("%d",&m);for(i=0;i<m;i++){scanf("%d%d",&a,&b);edge[i].s=a;edge[i].t=b;edge[i].next=headlist[a];headlist[a]=i;edge[i].next2=headlist2[b];//記錄反邊headlist2[b]=i;}kosaraju();output();}return 0;}

 

====================================================================

 

/*tarjanMemory 544KTime   63MS*/#include <iostream>using namespace std;#define MAXM 50010#define MAXV 10010#define min(a,b) (a>b?b:a)typedef struct{int s,t,next;}Edge;Edge edge[MAXM];int n,m,headlist[MAXV];int dfn[MAXV];//第一次訪問的步數int low[MAXV];//子樹中最早的步數int stap[MAXV],stop;//類比棧bool instack[MAXV];//是否在棧中int count;//記錄連通分量的個數int cnt;//記錄搜尋步數int belong[MAXV];//屬於哪個連通分量void init(){count=stop=cnt=0;memset(instack,false,sizeof(instack));memset(dfn,0,sizeof(dfn));}void tarjan(int x){int i;dfn[x]=low[x]=++cnt;stap[stop++]=x;instack[x]=true;for(i=headlist[x];i!=-1;i=edge[i].next){int a=edge[i].t;if(!dfn[a]){tarjan(a);low[x]=min(low[a],low[x]);}else if(instack[a])low[x]=min(dfn[a],low[x]);}if(low[x]==dfn[x]){count++;while(1){int tmp=stap[--stop];belong[tmp]=count;instack[tmp]=false;if(tmp==x) break;}}}void work(){init();for(int i=1;i<=n;i++)if(!dfn[i]) tarjan(i);}void output(){int i,j,outdegree[MAXV]={0};for(i=1;i<=n;i++)for(j=headlist[i];j!=-1;j=edge[j].next)if(belong[i]!=belong[edge[j].t]){outdegree[belong[i]]++;}memset(instack,0,sizeof(instack));for(i=1;i<=n;i++)if(!outdegree[belong[i]]) instack[i]=1;for(i=1;i<=n;i++)if(instack[i]) printf("%d ",i);printf("\n");}int main(){int i,a,b;while(~scanf("%d%d",&n,&m)){memset(headlist,-1,sizeof(headlist));for(i=0;i<m;i++){scanf("%d%d",&a,&b);edge[i].s=a;edge[i].t=b;edge[i].next=headlist[a];headlist[a]=i;}work();output();}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.