POJ 3687 Labeling Balls 逆向拓扑排序

链接:

poj3687

题意:

有N个标号为1~N的小球,重量(不包括断言)依次增加 ,现给出M句断言 ,断言格式为a b

表示小球a轻于小球b     要求根据重量大小依次输出1~N号小球应在的的位置(重量递增)不满足断言则输出-1

题解:

因为重量是依次增加的  不能按常规的构造edge[a][b]=1生成拓扑排序

既然关系格式和一般拓扑排序是相反的  我们可以尝试着构造反向边edge[b][a]=1

indegree[a]++;   再根据小球标号从后往前进行拓扑排序,即可得到一幅完整的从大

到小的拓扑排序。

注意:

1.题目要求输出1~N号小球的位置,而不是完整的拓扑排序。

2.再构造边edge[b][a]=1的时候不能进行indegree[a]++;因为会有重边。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int map[505][505];
int indegree[505];
int ans[505];
int m;
int topsort()
{
    int i,j,loc,k=m;
    for(i=0; i<m; i++)
    {
        for(j=m; j>0; j--)         //从后往前
            if(!indegree[j])
            {
                loc=j;
                break;
            }
        if(j==0)
            return 0;
        ans[loc]=k--;             //ans[k--]=loc;
        indegree[loc]=-1;
        for(j=1; j<=m; j++)
            if(map[loc][j])
                indegree[j]--;
    }
    return 1;
}
int main()
{
    int i,j,t,a,b,n;
    scanf("%d",&t);
    while(t--)
    {
        memset(indegree,0,sizeof(indegree));
        memset(map,0,sizeof(map));
        scanf("%d%d",&m,&n);
        while(n--)
        {
            scanf("%d%d",&a,&b);
            map[b][a]=1;
        }
        for(i=1;i<=m;i++)
            for(j=1;j<=m;j++)
            if(map[i][j])
            indegree[j]++;
        if(topsort())
        {
            for(i=1; i<m; i++)
                cout<<ans[i]<<' ';
            cout<<ans[i]<<endl;
        }
        else
            cout<<-1<<endl;
    }
    return 0;
}
时间: 2024-11-08 20:19:47

POJ 3687 Labeling Balls 逆向拓扑排序的相关文章

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

poj 3687 Labeling Balls 【拓扑排序】

题目链接:http://poj.org/problem?id=3687 注意重边 代码: #include <stdio.h> #include <ctime> #include <math.h> #include <limits.h> #include <complex> #include <string> #include <functional> #include <iterator> #include

HDU 3687 Labeling Balls(逆向拓扑)

Labeling Balls 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 the same label. The labeling satisfies several constrains like "The ball labeled wi

[ACM] POJ 3687 Labeling Balls (拓扑排序,逆向建边)

Labeling Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10161   Accepted: 2810 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

[ACM] POJ 3687 Labeling Balls (拓扑排序,反向生成端)

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

POJ - 3687 Labeling Balls (拓扑排序)

题意:N个点,给出M条两个点u.v,满足u比值小.给这N个点编号,要求排在前的比排在后的质量小,且编号不重复.求每点能得到最小编号的编号方法. 分析:用拓扑排序求解. 用优先队列来存待标记的点,编号大的点优先出队列,然后从大到小依次标记(编号小的优先肯定是错的,当时wa死了). 若求不出拓扑排序则答案无解. #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #i

poj 3687 Labeling Balls(拓补排序)

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 the same label. The labeling satisfies several constrains like "The ball labeled with a is lighter

POJ3687 Labeling Balls (拓扑排序)经典

Labeling Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11469   Accepted: 3295 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

POJ 3687 Labeling Balls

题目链接:https://vjudge.net/problem/POJ-3687 题目大意 有 N 个重量互不相同的球,标记为 1 ~ N,现给定 M 个重量约束条件,将 1 ~ N 单位的重量分配给每个球,如果能成功分配,输出重量序列(字典序尽量小),不能则输出 -1. 分析 一种错误的想法是先建立拓扑图,然后拓扑排序,每次取序号最小的节点从小到大分配重量,但这是不对的,这里举个反例:5 4 · 5 1 4 2 1 3 2 3. 正解是建立逆向拓扑图,然后拓扑排序,每次取序号最大的节点从大到小