POJ-3687-Labeling Balls

链接:https://vjudge.net/problem/POJ-3687

题意:

给n个求再个m个条件,a比b轻,找出n个求每个对应的最小重量,

同时保证1尽量小。2尽量小。。。

思路:

拓扑排序,反向建图。

刚开始正向建图没理解。

看题解才懂,题意要求1的重量尽量小,2的重量也尽量小。

所有并不是说当前判定的某几个小。

即不能按编号小的球,重量一定小来求。

所以反向建图,编号大的球重量一定大,这样跑拓扑排序就行了。

代码:

#include <iostream>
#include <memory.h>
#include <vector>
#include <map>
#include <algorithm>
#include <cstdio>
#include <math.h>
#include <queue>
#include <string>
#include <stack>
#include <iterator>
#include <stdlib.h>
#include <time.h>
#include <assert.h>

using namespace std;
typedef long long LL;
const int MAXN = 200 + 10;

vector<int> G[MAXN];
int in[MAXN], res[MAXN];
int n, m;

void Init()
{
    for (int i = 1;i <= n;i++)
        G[i].clear();
    memset(in, 0, sizeof(in));
    memset(res, 0, sizeof(res));
}

bool Tupo()
{
    priority_queue<int> que;
    for (int i = 1;i <= n;i++)
        if (in[i] == 0)
            que.push(i);
    int pos = n;
    while (!que.empty())
    {
        int u = que.top();
        que.pop();
        res[u] = pos--;
        for (int i = 0;i < G[u].size();i++)
        {
            if (--in[G[u][i]] == 0)
                que.push(G[u][i]);
        }
    }
    if (pos == 0)
        return true;
    return false;
}

int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d%d", &n, &m);
        Init();
        int l, r;
        for (int i = 1;i <= m;i++)
        {
            scanf("%d%d", &l, &r);
            G[r].push_back(l);
            ++in[l];
        }
        if (Tupo())
        {
            printf("%d", res[1]);
            for (int i = 2;i <= n;i++)
                printf(" %d", res[i]);
            printf("\n");
        }
        else
            printf("-1\n");
    }

    return 0;
}

  

posted @ 2019-04-16 15:10  YDDDD  阅读(121)  评论(0编辑  收藏  举报