今天补图论的题,发现自己又对拓扑排序这个算法有了些生疏,今天在这里写一下模板,这里按照入度的多少排序
复杂度(n*n)
//注意此模板规定点是从零开始,若不是则需要改动,并且输入不存在重复边的情况
#include <bits/stdc++.h>
using namespace std;
const int maxn=1000+10;
const int INF=0x3f3f3f3f;
bool G[maxn][maxn];
int deg[maxn],V,E;
void toposort()
{
int k;
for(int i=0;i<V;i++)//不断地循环,不断地寻找度数为0的边
{
for(int j=0;j<V;j++)
{
if(deg[j]==0)
{
printf("%d%c",j,i==n?' ':'\n');
deg[j]--;//这里要还原为-1
k=j;
break;
}
}
for(int j=0;j<V;j++)//消除这个边与其他边的联系
{
if(G[k][j]==true)
{
G[k][j]=false;
deg[j]--;
}
}
}
}
int main()
{
scanf("%d%d",&V,&E);
memset(G,0,sizeof(G));
memset(deg,0,sizeof(deg));
for(int i=0;i<E;i++)
{
int p,q; scanf("%d %d",&p,&q);//进行统计标记
G[p][q]=true;
deg[q]++;
}
toposort();
return 0;
}
复杂度O(V + E)(这里使用了链式前向星,前向星与链式前向星)
//此模板依旧是从零开始
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int INF=0x3f3f3f3f;
struct node
{
int next;
int to;
}G[maxn];
int head[maxn],deg[maxn];
int cnt,V,E;
void toposort()
{
priority_queue<int ,vector<int>,greater<int> > que;
for(int i=0;i<V;i++)
{
if(deg[i]==0)
{
que.push(i);
deg[i]--;
}
}
int k=1;
while(!que.empty())
{
int u=que.top(); que.pop();
printf("%d%c",u,k++==V?'\n':' ');
for(int i=head[u];i!=-1;i=G[i].next)
{
int v=G[i].to; deg[v]--;
if(deg[v]==0) que.push(v);
}
}
}
int main()
{
while(scanf("%d %d",&V,&E)==2)
{
memset(head,-1,sizeof(head));
memset(deg,0,sizeof(deg));
cnt=0;
while(E--)
{
int u,v,i; scanf("%d %d",&u,&v);
for(i=head[u];i!=-1;i=G[i].next)
{
if(G[i].to==v) break;
}
if(i==-1)
{
deg[v]++;
G[u].to=v;
G[u].next=head[u];
head[u]=cnt++;
}
}
toposort();
}
return 0;
}
以上的输出顺序均是按照字典序进行的输出,