关于拓扑排序的模板

今天补图论的题,发现自己又对拓扑排序这个算法有了些生疏,今天在这里写一下模板,这里按照入度的多少排序

复杂度(V*V)

//注意此模板规定点是从零开始,若不是则需要改动,并且输入不存在重复边的情况
#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;
}

以上的输出顺序均是按照字典序进行的输出,

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值