poj3687Labeling Balls(反向拓扑+优先队列)

题目链接:

啊哈哈,点我点我

题意:就是给了m个限制条件,然后形式是啊a,b就是说编号为a的小球比编号为b的小球青,最后输出字典序最小的序列出来。

思路:如果正常的正向建图的话,有可能得到的不是字典序最小的序列。。比如有这样一个例子1->5->4,6->2->3,如果正向建图得到的序列将会是

5 2 1 3 4 6,,而正确的序列式怎么感觉碰到一些题目按字典序都要逆向枚举啊。。1 3

4 6 5 2.。所以要反向拓扑。。

题目:

Labeling Balls

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 10732   Accepted: 3045

Description

Windy has N balls of distinct weights from 1 unit to N units. Now he tries to label them with 1 to N in such a way that:

  1. No two balls share the same label.
  2. The labeling satisfies several constrains like "The ball labeled with a is lighter than the one labeled with b".

Can you help windy to find a solution?

Input

The first line of input is the number of test case. The first line of each test case contains two integers, N (1 ≤ N ≤ 200) and M (0 ≤ M ≤ 40,000). The next M line each contain two integers a and b indicating
the ball labeled with a must be lighter than the one labeled with b. (1 ≤ a, b ≤ N) There is a blank line before each test case.

Output

For each test case output on a single line the balls‘ weights from label 1 to label N. If several solutions exist, you should output the one with the smallest weight for label 1, then with the smallest weight for label 2, then with the smallest
weight for label 3 and so on... If no solution exists, output -1 instead.

Sample Input

5

4 0

4 1
1 1

4 2
1 2
2 1

4 1
2 1

4 1
3 2

Sample Output

1 2 3 4
-1
-1
2 1 3 4
1 3 2 4

Source

POJ Founder Monthly Contest – 2008.08.31, windy7926778

代码为:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
using  namespace std;

const int maxn=200+10;
vector<int>vec[maxn];
int in[maxn],map[maxn][maxn],ans[maxn];
int t,n,m,u,v;

void topo()
{
    priority_queue<int>Q;
    memset(ans,0,sizeof(ans));
    while(!Q.empty())  Q.pop();
    int cal=n,id=0,flag=0;
    for(int i=1;i<=n;i++)
    {
        if(in[i]==0)
          Q.push(i);
    }
    while(!Q.empty())
    {
        int temp=Q.top();
        Q.pop();
        ans[temp]=cal--;
        for(int i=0;i<vec[temp].size();i++)
        {
            if(--in[vec[temp][i]]==0)
                Q.push(vec[temp][i]);
        }
    }
    if(cal!=0)
        {
            cout<<"-1"<<endl;
            return;
        }
    for(int i=1;i<n;i++)
        printf("%d ",ans[i]);
    printf("%d\n",ans[n]);
}

int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        memset(map,0,sizeof(map));
        for(int i=1;i<=n;i++)
        {
            in[i]=0;
            vec[i].clear();
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&u,&v);
            if(map[u][v]==0)
            {
                map[u][v]=1;
                vec[v].push_back(u);
                in[u]++;
            }
        }
        topo();
    }
    return 0;
}

poj3687Labeling Balls(反向拓扑+优先队列)

时间: 2024-11-08 18:15:24

poj3687Labeling Balls(反向拓扑+优先队列)的相关文章

HDU 4857 (反向拓扑排序 + 优先队列)

题意:有N个人,M个优先级a,b表示a优先于b,并且每个人有个编号的优先级,输出顺序. 思路来自:与PKU3687一样 在基本的拓扑排序的基础上又增加了一个要求:编号最小的节点要尽量排在前面:在满足上一个条件的基础上,编号第二小的节点要尽量排在前面:在满足前两个条件的基础上,编号第三小的节点要尽量排在前面--依此类推.(注意,这和字典序是两回事,不可以混淆.) 如图 1 所示,满足要求的拓扑序应该是:6 4 1 3 9 2 5 7 8 0. 图 1 一个拓扑排序的例子 一般来说,在一个有向无环图

HDU 4857 逃生 (优先队列+反向拓扑)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 解题报告:有n个点,有m个条件限制,限制是像这样的,输入a  b,表示a必须排在b的前面,如果不能确定两个数谁排在前面则尽量把小的排在前面. 首先把出度为0的点加入到优先队列中,然后每次用优先队列中弹出的点去更新其它点的出度,更新的同时如果又有其它点的出度为0的话又加到优先队列中, 最后按照从优先队列中出队的反序输出就可以了.我还是不懂为什么按照入度为0然后加入到优先队列然后正序输出这样为什么

POJ3687Labeling Balls

Labeling Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14278   Accepted: 4162 Description Windy has N balls of distinct weights from 1 unit to N units. Now he tries to label them with 1 to N in such a way that: No two balls share

逃生(HDU4857 + 反向拓扑排序)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 题面是中文题面,就不解释题意了,自己点击链接去看下啦~这题排序有两个条件,一个是按给定的那个序列(即输入的u,v,优先级最高),一个是序号从小到大(优先级次之).正向的话由于这两个条件不好维护,所以就想着用反向拓扑排序来实现.首先记录每个节点的出度,然后用优先队列来维护顺序(使用默认的从大到小排序),最后反向输出即可. 代码实现如下: 1 #include <queue> 2 #includ

杭电2647--Reward(反向拓扑)

Reward Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5863    Accepted Submission(s): 1797 Problem Description Dandelion's uncle is a boss of a factory. As the spring festival is coming , he wa

Light oj 1251 - Forming the Council 【2-sat】【推断是否存在可行解 + 反向拓扑输出可行解】

1251 - Forming the Council problem=1251" style="color:rgb(79,107,114)"> PDF (English) problem=1251" style="color:rgb(79,107,114)">Statistics problem=1251" style="color:rgb(79,107,114)">Forum Time Limit

Light oj 1251 - Forming the Council 【2-sat】【判断是否存在可行解 + 反向拓扑输出可行解】

1251 - Forming the Council PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB In a city there are n voters, and m people formed the Govt. council. The council members are numbered from 1 to m. Now everyone is complaining that

反向拓扑排序

对于初始没有进行编号,且要求数字小的尽可能在前面 需要进行反向拓扑排序 真的看不懂 反正需要进行 邻接表优化 传送门 传送门 #include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int N = 3e4+5; int n,m,cnt; bool mp[N][N]; int du[N],head[N]; int a

POJ 3687 Labeling Balls【拓扑排序 优先队列】

题意:给出n个人,m个轻重关系,求满足给出的轻重关系的并且满足编号小的尽量在前面的序列 因为输入的是a比b重,但是我们要找的是更轻的,所以需要逆向建图 逆向建图参看的这一篇http://blog.csdn.net/scf0920/article/details/28108243 然后用优先队列来实现的参看的这一篇 http://ycool.com/post/u9ahrwg#algo3 1 #include<iostream> 2 #include<cstdio> 3 #includ