Labeling Balls POJ - 3687 (拓扑排序 反向建边 优先队列)

题目思路

在学长拉的图论专题里面找的拓扑排序的题
做的第一道就这么麻烦 学长真是好狠的心
看了好久都没搞懂为什么要反向建边
后来发现我读了个假题
读懂后还是不明白 看了无数个博客
最后找到了个跟着题类似的题的博客
大概弄懂了反向建边的原因
https://www.cnblogs.com/zznulw/p/6638571.html
不懂得话可以看下这个博客
然后还要注意的是输出要的是标号的重量 不是输出每个重量的标号
还有数组开打了会mle 和 tle 开到200多就好了

ac代码

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 2e2+10;
const int inf = 0x3f3f3f3f;
const ll llinf =0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;

int a[maxn],in[maxn];
int vis[maxn][maxn];
vector<int>vec[maxn];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        ms(in,0);ms(vis,0);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            if(!vis[y][x])
            {
                vis[y][x]=1;
                vec[y].push_back(x);
                in[x]++;
            }

        }
        priority_queue<int>q;
        for(int i=1;i<=n;i++)
        {
            if(in[i]==0)q.push(i);
        }
        vector<int>ans;
        while(!q.empty())
        {
            int p=q.top();
            q.pop();
            ans.push_back(p);
            for(int i=0;i<vec[p].size();i++)
            {
                int y=vec[p][i];
                in[y]--;
                if(in[y]==0)
                {
                    q.push(y);
                }

            }
        }
        if(ans.size()==n)
        {
            for(int i=0,j=n;i<ans.size();i++,j--)
            {
                a[ans[i]]=j;
            }
            for(int i=1;i<=n;i++)
                printf("%d ",a[i]);
            printf("\n");
        }else
        {
            printf("-1\n");
        }
        ans.clear();
        for(int i=1;i<=n;i++)
            vec[i].clear();

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值