POJ - 3687 Labeling Balls (拓扑)

(点击此处查看原题)

题意

此处有n盏灯,编号为1~n,每盏灯的亮度都是唯一的,且在1~n范围之间,现已知m对灯之间的关系:a b ,说明灯a的亮度比灯b小,求出每盏灯的亮度,要求字典序最小(编号小的灯亮度尽量小),使之满足m对关系,如果不存在,输出-1

解题思路

每对灯的关系:a b ,说明灯a的亮度比灯b小,同时也说明a的完成时间比b早(AOV网中的概念),这种关系可以用拓扑排序很好地处理,而由于这个题目要求字典序最小,为此将队列改为优先队列,使得编号大的灯先出队,并为其赋予较大的拓扑序,这样便可以使得字典序最小了,最后我们将所有点都赋予了拓扑序,随后和m对关系一一比较,判断是否满足要求,满足则输出所得拓扑序,否则输出-1

代码区

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
#include<fstream>
#include<vector>
#include<stack>
#include <map>
#include <iomanip>

#define bug cout << "**********" << endl
#define show(x, y) cout<<"["<<x<<","<<y<<"] "
#define LOCAL = 1;
using namespace std;
typedef long long ll;
const ll inf = 1e18 + 10;
const ll mod = 1e9 + 7;
const int Max = 1e6 + 10;
const int Max2 = 3e2 + 10;

int n, m;
vector<int> edge[Max2];        //邻接表建图
pair<int, int> way[Max];    //存储m对关系
map<pair<int,int>,bool>mp;    //用于判断重边
int in_d[Max2];                //记录入度
int id[Max2], now;             //记录拓扑序

void init()
{
    for (int i = 0; i < Max2; i++)
        edge[i].clear();
    memset(id, 0, sizeof(id));
    now = n;
    memset(in_d,0,sizeof(in_d));
    mp.clear();
}

void topoSort()
{
    priority_queue<int> q;
    for (int i = n; i >= 1; i--)
    {
        if (in_d[i] == 0)
            q.push(i);
    }
    while (!q.empty())
    {
        int u = q.top();
        q.pop();
        id[u] = now--;
        for(int i = 0 ;i < (int)edge[u].size() ;i ++)
        {
            int v = edge[u][i];
            if(id[v]) continue;
            in_d[v]--;
            if(in_d[v] == 0)
            {
                q.push(v);
            }
        }
    }
}

int main()
{
#ifdef LOCAL
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif
    int T;
    scanf("%d", &T);
    while (T--)
    {
        scanf("%d%d", &n, &m);
        init();
        bool ok = true;
        for (int i = 1, u, v; i <= m; i++)
        {
            scanf("%d%d", &u, &v);
            if(u == v)
            {
                ok = false;
                continue;
            }
            if(!mp[make_pair(u,v)])
            {
                edge[v].push_back(u);
                in_d[u]++;
            }
            way[i] = make_pair(u, v);
            mp[way[i]] = true;
        }
        topoSort();

        for (int i = n; i >= 1; i--)
        {
            if (id[i] == 0)
            {
                id[i] = now--;
            }
        }
        for (int i = 1; i <= m; i++)
        {
            if (id[way[i].first] > id[way[i].second])
            {
                ok = false;
                break;
            }
        }
        if (!ok)
        {
            printf("-1\n");
        }
        else
        {
            for (int i = 1; i <= n; i++)
            {
                printf("%d%c", id[i], i != n ? ' ' : '\n');
            }
        }
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/winter-bamboo/p/11419577.html