POJ2367——Genealogical tree(拓撲排序模板)
阿新 • • 發佈:2019-02-16
題目描述:
題目來源: POJ2367:http://poj.org/problem?id=2367
題目大意:
求1到n的其中一種拓撲序,保證存在一種拓撲序。輸入格式是:第一行讀入n,接下來n行,第i+1行表示有由i指向其他點的邊,以0結尾。(直接一個0就是它沒有連向任何點)。
樣例輸入:
5
0
4 5 1 0
1 0
5 3 0
3 0
樣例輸出:
2 4 5 3 1
題目分析:
一道拓撲排序模板題,而且題目保證是有解的,就不用判有沒有環什麼的,直接求就行。
不會拓撲序的請看我的講解:http://blog.csdn.net/qianguch/article/details/77411160
附程式碼:
方法1:尋找入度為0的點
#include<iostream>
#include<cstring>
#include<string>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<ctime>
#include<iomanip>
#include<cctype>
#include<algorithm>
using namespace std;
const int maxn=110;
int n,du[maxn],to[maxn*maxn],nxt[maxn*maxn],first[maxn],tot,y;
queue<int>q;
void create(int u,int v)
{
tot++;
nxt[tot]=first[u];
first[u]=tot;
to[tot]=v;
}
void find()
{
while(!q.empty())
{
int u=q.front();
q.pop();
printf ("%d ",u);
for(int e=first[u];e;e=nxt[e])
{
du[to[e]]--;
if(du[to[e]]==0) q.push(to[e]);
}
}
}
int main()
{
//freopen("lx.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++)
while(scanf("%d",&y),y!=0)
{
create(i,y);
du[y]++;
}
for(int i=1;i<=n;i++)
if(du[i]==0)
q.push(i);
find();
return 0;
}
方法2:dfs
#include<iostream>
#include<cstring>
#include<string>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<ctime>
#include<iomanip>
#include<cctype>
#include<algorithm>
using namespace std;
const int maxn=110;
int n,ans[maxn],to[maxn*maxn],nxt[maxn*maxn],first[maxn],tot,y,num;
bool vis[maxn];
void create(int u,int v)
{
tot++;
nxt[tot]=first[u];
first[u]=tot;
to[tot]=v;
}
void dfs(int u)
{
for(int e=first[u];e;e=nxt[e])
if(vis[to[e]]==false)
{
vis[to[e]]=true;
dfs(to[e]);
}
ans[++num]=u;
}
int main()
{
//freopen("lx.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++)
while(scanf("%d",&y),y!=0)
create(i,y);
for(int i=1;i<=n;i++)
if(vis[i]==false)
{
vis[i]=true;
dfs(i);
}
for(int i=num;i>=1;i--)
printf("%d ",ans[i]);
return 0;
}