POJ - 3687 Labeling Balls (拓扑排序)

题意:N个点,给出M条两个点u、v,满足u比值小。给这N个点编号,要求排在前的比排在后的质量小,且编号不重复。求每点能得到最小编号的编号方法。

分析:用拓扑排序求解。

用优先队列来存待标记的点,编号大的点优先出队列,然后从大到小依次标记(编号小的优先肯定是错的,当时wa死了)。

若求不出拓扑排序则答案无解。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
typedef long long LL;
using namespace std;
const int maxn =5e2+5;
const int maxm = 4e4+5;
struct Edge{
    int v,next;
}edge[maxm];
int head[maxn],tot,cnt;
int ind[maxn];
void init()
{
    memset(ind,0,sizeof(ind));
    memset(head,-1,sizeof(head));
    tot=0;
}

void AddEdge(int u,int v)
{
    edge[tot] = (Edge){v,head[u]};
    head[u] = tot++;
}

int ans[maxn];
bool topo(int n)
{
    cnt=n;
    priority_queue<int> Q;
    for(int i =1;i<=n;++i){
        if(!ind[i]){
            Q.push(i);
        }
    }
    while(!Q.empty()){
        int u = Q.top() ;Q.pop();
        ans[u] = cnt--;
        for(int i=head[u];~i;i=edge[i].next){
            int v = edge[i].v;
            ind[v]--;
            if(!ind[v]){
                Q.push(v);
            }
        }
    }
    if(cnt!=0) return false;
    else return true;
}
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    int N,M,m,q,u,v,cas=1;
    int T; scanf("%d",&T);
    while(T--){
        init();
        bool flag = false;
        scanf("%d%d",&N,&M);
        while(M--){
            scanf("%d%d",&v,&u);
            //if(u==v) flag = true;
            AddEdge(u,v);
            ind[v]++;
        }
        if(flag || !topo(N)) printf("-1\n");
        else{
            for(int i=1;i<N;++i){
                printf("%d ",ans[i]);
            }
            printf("%d\n",ans[N]);
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/xiuwenli/p/9497669.html

时间: 2024-10-16 19:18:29

POJ - 3687 Labeling Balls (拓扑排序)的相关文章

[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个轻重关系,求满足给出的轻重关系的并且满足编号小的尽量在前面的序列 因为输入的是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 逆向拓扑排序

链接: poj3687 题意: 有N个标号为1~N的小球,重量(不包括断言)依次增加 ,现给出M句断言 ,断言格式为a b 表示小球a轻于小球b     要求根据重量大小依次输出1~N号小球应在的的位置(重量递增)不满足断言则输出-1 题解: 因为重量是依次增加的  不能按常规的构造edge[a][b]=1生成拓扑排序 既然关系格式和一般拓扑排序是相反的  我们可以尝试着构造反向边edge[b][a]=1: indegree[a]++;   再根据小球标号从后往前进行拓扑排序,即可得到一幅完整的

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

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. 正解是建立逆向拓扑图,然后拓扑排序,每次取序号最大的节点从大到小

POJ 3687 Labeling Balls(特殊的拓扑排序)

题目链接:http://poj.org/problem?id=3687 题目: 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

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

poj 1270 Following Orders(拓扑排序+dfs)

大致题意:每个样例包含两行,第一行输入n个字符,可能是无序的.第二行输入成对的a b,代表a要在b前面.输出所有的符合这样的序列. 思路:很明显的拓扑排序.要输出所有的序列,那么就从入度为0的点进行dfs,每次选择一个入度为0的点,加入输出序列并把与它相邻的点的入度减一.dfs结束后要把状态再改回来. #include <stdio.h> #include <algorithm> #include <set> #include <map> #include