要进行拓扑排序之前,该图要是有向无环图。
排序方法:
1、从有向图中选取一个没有前驱的顶点,并输出之
;2、从有向图中删去此顶点以及所有以它为尾的弧;
3、重复上述两步,直至图空,或者图不空但找不到无前驱的顶点为止。
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
const int maxn=100001;
const int inf=1<<29;
int e,head[maxn],pnt[maxn],nxt[maxn];
int cnt_in[maxn],cnt_out[maxn];
bool vis[maxn];
int n,m,k;
void AddEdge(int u,int v)
{
pnt[e]=v;nxt[e]=head[u];head[u]=e++;
}
int main()
{
int tt;
scanf("%d",&tt);
while(tt--)
{
scanf("%d%d",&n,&m);
e=0;
memset(head,-1,sizeof(head));
memset(cnt_in,0,sizeof(cnt_in));
memset(cnt_out,0,sizeof(cnt_out));
memset(vis,0,sizeof(vis));
for(int i=0;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
AddEdge(u,v);
cnt_out[u]++;
cnt_in[v]++;
}
/*for(int i=1;i<=n;i++)
{
printf("%d :",i);
printf("%d %d\n",cnt_in[i],cnt_out[i]);
}*/
int cnt=0;
int kj[maxn];
while(1)
{
int f=0;
for(int u=1;u<=n;u++)
{
if(cnt_in[u]==0&&!vis[u])
{
f=1;
for(int i=head[u];i!=-1;i=nxt[i])
{
cnt_in[pnt[i]]--;
}
kj[cnt++]=u;
vis[u]=1;
}
}
if(cnt==n||f==0)
break;
}
int k2=0;
for(int i=1;i<=n;i++)//如果所有的数字的入度都为0,代表这是一个无环图。
if(vis[i]==0)
k2=1;
if(k2==1)
puts("Wrong");
else
puts("Correct");
}
return 0;
}
而拓扑排序 只要将上面的数组kj[]从小到大输出即可。
for(int i=0;i<cnt;i++)
printf("%d ",kj[i]);