对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。——摘自百度百科。
具体的实现:
1、找到一个入度为零的点,把它丢进队列。
2、把这个点以及与这个点相连的边都删去。
3、重复1、2直到图为空。
对,又有个裸题 poj 2367 Genealogical tree链接
就是直接把拓扑排序后的序列输出即可。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int MAXN=100+10;
int ans[MAXN],in[MAXN];
bool vis[MAXN][MAXN];
int n,cnt;
queue<int>q;
void sort()
{
while(!q.empty())
{
int tp=q.front();
q.pop();
ans[++cnt]=tp;
for(int i=1;i<=n;i++)
{
if(vis[tp][i])
{
vis[tp][i]==0;
in[i]--;
}
}
for(int i=1;i<=n;i++)
{
if(in[i]==0)
{
q.push(i);
in[i]=-1;
}
}
}
}
int main()
{
while(~scanf("%d",&n))
{
cnt=0;
int t;
for(int i=1;i<=n;i++)
{
while(scanf("%d",&t)&&t)
{
in[t]++;
vis[i][t]=1;
}
}
for(int i=1;i<=n;i++)
{
if(in[i]==0)
{
q.push(i);
in[i]=-1;
}
}
sort();
for(int i=1;i<=cnt;i++)
printf("%d ",ans[i]);
puts("");
}
return 0;
}
还有一个裸题… codevs 2833 奇怪的梦境链接
只要把不能进行排序的数输出即可…
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int MAXN=10000+10;
int ans[MAXN],in[MAXN];
bool vis[MAXN][MAXN];
int n,cnt;
queue<int>q;
void sort()
{
while(!q.empty())
{
int tp=q.front();
q.pop();
ans[++cnt]=tp;
for(int i=1;i<=n;i++)
{
if(vis[tp][i])
{
vis[tp][i]==0;
in[i]--;
}
}
for(int i=1;i<=n;i++)
{
if(in[i]==0)
{
q.push(i);
in[i]=-1;
}
}
}
}
int main()
{
int m;
scanf("%d%d",&n,&m);
cnt=0;
int t;
memset(in,0,sizeof(in));
memset(vis,0,sizeof(vis));
for(int i=1;i<=m;i++)
{
int ff,tt;
scanf("%d%d",&ff,&tt);
in[tt]++;
vis[ff][tt]=1;
}
for(int i=1;i<=n;i++)
{
//cout<<i<<" "<<in[i]<<endl;
if(in[i]==0)
{
q.push(i);
in[i]=-1;
}
}
sort();
if(cnt==n)
puts("o(∩_∩)o");
else
{
puts("T_T");
printf("%d\n",n-cnt);
}
return 0;
}
//以后有拓扑排序的应用我还会在这里发的~(≧▽≦)/~