1. 程式人生 > >POJ 2553 The Bottom of a Graph

POJ 2553 The Bottom of a Graph

har tac memset pac ack cpp namespace include string

我的第一道tarjin

要註意兩點,有向圖一定要判斷點是否在棧中

彈棧的時候不能判斷low[x]==low[stack[top]]

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN=5005;
const int MAXM=5000005;
inline int read(){
	int x=0,f=1,ch=getchar();
	while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
	while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
	return x*f;
}
int nxt[MAXM],to[MAXM],h[MAXN],cnt;
inline void add(int x,int y){
	nxt[cnt]=h[x];to[cnt]=y;h[x]=cnt++;
}
int dfn[MAXN],low[MAXN],vis[MAXN],tim;
int stack[MAXN],top;
int shu[MAXN],num;
inline void dfs(int x){
	dfn[x]=low[x]=++tim;
	vis[x]=1;
	stack[++top]=x;
	for(int i=h[x];i!=-1;i=nxt[i]){
		if(!dfn[to[i]]) dfs(to[i]),low[x]=min(low[x],low[to[i]]);
		else if(vis[to[i]]) low[x]=min(low[x],dfn[to[i]]);
	}
	if(dfn[x]==low[x]){
		num++;
		while(stack[top]!=x&&top) shu[stack[top]]=num,vis[stack[top]]=0,top--;
		shu[stack[top]]=num,vis[stack[top]]=0,top--;
	}
}
int du[MAXN];
int main(){
	int n=read();
	while(n!=0){
		memset(h,-1,sizeof(h));
		memset(du,0,sizeof(du));
		memset(dfn,0,sizeof(dfn));
		memset(vis,0,sizeof(vis));
		top=0,tim=0,cnt=0,num=0;
		int m=read();
		for(int i=1;i<=m;i++){
			int x=read(),y=read();
			add(x,y);
		}
		for(int i=1;i<=n;i++)
			if(!dfn[i])
				dfs(i);
		for(int i=1;i<=n;i++)
			for(int j=h[i];j!=-1;j=nxt[j])
				if(shu[i]!=shu[to[j]])
					du[shu[i]]++;
		for(int i=1;i<=n;i++)
			if(!du[shu[i]])
				printf("%d ",i);
		puts("");
		n=read();
	}
	return 0;
}

  

POJ 2553 The Bottom of a Graph