The Bottom of a Graph http://poj.org/problem?id=2553
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
const int maxn = 5050;
struct node{
int to,net;
}edge[maxn*maxn];
stack<int> s;
int n,m,a,b;
int index = 0;
int head[maxn],tot=1;
int instack[maxn];
int belong[maxn],scc=0;
int dfn[maxn],low[maxn];
int out[maxn];
void addedge(int u,int v)
{
edge[tot].to = v;
edge[tot].net = head[u];
head[u] = tot++;
}
void tarjan(int u)
{
dfn[u] = low[u] = ++index;
instack[u] = 1;
s.push(u);
for(int i=head[u];i!=-1;i=edge[i].net)
{
int v = edge[i].to;
if(!dfn[v])
{
tarjan(v);
low[u] = min(low[v],low[u]);
}
else if(instack[v])
{
low[u] = min(low[u],dfn[v]);
}
}
if(dfn[u] == low[u])
{
++scc;
int tem;
do{
tem = s.top();
s.pop();
belong[tem] = scc;
instack[tem] = 0;
}while(tem != u && !s.empty());
}
}
void initalize()
{
index = 0;
tot = 1;
scc = 0;
memset(head,-1,sizeof(head));
memset(instack,0,sizeof(instack));
memset(belong,0,sizeof(belong));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
while(!s.empty()) s.pop();
memset(out,0,sizeof(out));
}
int main()
{
while(~scanf("%d",&n)&&n)
{
scanf("%d",&m);
initalize();
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
addedge(a,b);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i])
tarjan(i);
}
for(int i=1;i<=n;i++)
{
for(int j=head[i];j!=-1;j=edge[j].net)
{
if(belong[i] != belong[edge[j].to] )
{
out[belong[i]]++;
}
}
}
int mark = 1;
for(int i=1;i<=n;i++)
{
if(out[belong[i]] == 0)
{
if(mark)
{
printf("%d",i);
mark = 0;
}
else printf(" %d",i);
}
}
printf("\n");
}
}
受欢迎的牛
https://vjudge.net/problem/HYSBZ-1051
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
const int maxn = 10100;
struct node{
int to,net;
}edge[50010];
stack<int> s;
int n,m,a,b;
int idx = 0;
int head[maxn],tot=1;
int instack[maxn];
int belong[maxn],scc=0;
int dfn[maxn],low[maxn];
int out[maxn];
void addedge(int u,int v)
{
edge[tot].to = v;
edge[tot].net = head[u];
head[u] = tot++;
}
void tarjan(int u)
{
dfn[u] = low[u] = ++idx;
instack[u] = 1;
s.push(u);
for(int i=head[u];i!=-1;i=edge[i].net)
{
int v = edge[i].to;
if(!dfn[v])
{
tarjan(v);
low[u] = min(low[v],low[u]);
}
else if(instack[v])
{
low[u] = min(low[u],dfn[v]);
}
}
if(dfn[u] == low[u])
{
++scc;
int tem;
do{
tem = s.top();
s.pop();
belong[tem] = scc;
instack[tem] = 0;
}while(tem != u && !s.empty());
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
idx = 0;
tot = 1;
scc = 0;
memset(head,-1,sizeof(head));
memset(instack,0,sizeof(instack));
memset(belong,0,sizeof(belong));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
while(!s.empty()) s.pop();
memset(out,0,sizeof(out));
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
addedge(a,b);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i])
tarjan(i);
}
for(int i=1;i<=n;i++)
{
for(int j=head[i];j!=-1;j=edge[j].net)
{
if(belong[i] != belong[edge[j].to] )
{
out[belong[i]]++;
}
}
}
int vac = 0;
for(int i=1;i<=n;i++)
{
if(out[belong[i]] == 0)
{
vac++;
}
}
printf("%d\n",vac);
}
}
Genealogical tree
https://vjudge.net/problem/POJ-2367
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
const int maxn=105;
int tot,n,m,k,a;
int head[maxn];
int in[maxn];
int rec[maxn];
struct node
{
int to,net;
} edge[maxn*maxn];
void addedge(int u,int v)
{
edge[tot].to=v;
edge[tot].net=head[u];
head[u]=tot++;
}
void topo()
{
queue<int>q;
for(int i=1; i<=n; i++)
{
if(in[i]== 0)
q.push(i);
}
while(!q.empty())
{
int u=q.front();
q.pop();
rec[k++]=u;
for(int i=head[u]; i!=-1; i=edge[i].net)
{
int v=edge[i].to;
in[v]--;
if(in[v]==0)
q.push(v);
}
}
}
int main()
{
while(~scanf("%d",&n))
{
tot=0;
memset(head,-1,sizeof(head));
for(int i=1;i<=n;i++)
{
for(int j=0;j<1000;j++)
{
scanf("%d",&a);
if(a == 0) break;
else
{
addedge(i,a);
in[a]++;
}
}
}
k=0;
topo();
for(int i=0 ; i<k;i++)
if(i==k-1) printf("%d\n",rec[i]);
else printf("%d ",rec[i]);
}
}