Labeling Balls

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other)
Total Submission(s) : 20   Accepted Submission(s) : 10
Problem 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
PKU
前言:纠结了好久的一道题目,缘于题目的意思不够明白;
(PS:一开始以为编号是乱序的,告诉你a编号和b编号的轻重关系,让你求全部编号的轻重的拓扑关系、、、
  其实,编号已经是固定好的从左往右分别是1~N编号)
  1,输入的a,b表示编号a的球比编号b的球轻(j既为a位置的球比b位置的球轻);
  2,输出的是,依次出编号1~N编号的球的重量。(既为位置1~N球的重量,囧囧囧、、、、)
  3,注意输出要求的这一句话:
     “ 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...”,意思既为:编号1的球尽可能的轻,编号2的球尽可能轻...       优先级是从编号小道编号大。也就是说,输出的重量,尽可能的吧重量比较小的放在前面。
  4,如果之间采用正向的拓扑是不可行的,因为正向拓扑的话,既为把这些编号看出是重量,然后从1~N依次获取  (入度为0且字典序最小的点)因为其求出来的是按照字典序的顺序求的,这样求解方式并不是正常的,
    好比如测试样例子:
      5 4
      1 4
      4 2
      5 3
      3 2
    你用正向的拓扑求出来的结果会是:1 4 5 3 2,你会发现 这个样例并没有满足最后一组要求(3 2)=>第三个位置    的球的重量要小于第二个位置球的重量,这样求解出来的结果便是错误的了。
    我看要求的是编号从小到大(1~N)的重量,且希望编号越小的球的重量也越小,也就是说,重量越大的球的     尽量赋给编号比较大的球。按照这个思路,我们这样就可以用反向拓扑来实现(其实就是箭头反向),只需要
    对正向拓扑进行一些修改即可,详细修改点请看代码二:
              
题目大意:
 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 205
int InD[];
int Edge[][];
void MakeSet(int Len)
{
int i;
for(i=;i<=Len;i++)
InD[i]=;
return;
}
int ToPoSort(int n,int* ret)
{
int i,j,k;
for(j=n;j>=;j--)
{
for(i=n;i>=;i--)
if(InD[i]==)
{
InD[i]--;
ret[i]=j;
for(k=;k<=n;k++)
if(Edge[i][k]==)
InD[k]--;
break;
}
if(i<)break;
}
if(j<=)
return ;
else
return ;
} int main()
{
int N,M,i,a,b,ID[],T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&N,&M);
MakeSet(N);
memset(Edge,,sizeof(Edge));
memset(ID,,sizeof(ID));
for(i=;i<M;i++)
{
scanf("%d%d",&a,&b);
if(Edge[b][a]==)
{
Edge[b][a]=;
InD[a]++;
}
}
if(ToPoSort(N,ID))
{
for(i=;i<=N;i++)
{
printf("%d",ID[i]);
if(i!=N)putchar();
}
putchar();
}
else
printf("-1\n");
}
return ;
}

修改:2015.2.28(邻接表)

 #include <iostream>
#include <stdio.h>
#include <string.h>
#include <map>
using namespace std;
#define MAX 215
int InD[MAX];/*InD[i]记录点i的入度*/
int First[MAX];/*First[i]头结点的第一条边的编号*/
struct edge
{
int TO;/*点*/
int Next;/*下一条边的编号*/
}ID[MAX*MAX]; /*边表,无向图的边数记得多弄些*/
int SIGN; /*链表的边数,链表的边数=无向图边数*2=有向图边数*/
void Add_E(int x,int y)/*添加点+更新入度操作*/
{
ID[SIGN].TO=y;
InD[y]++;
ID[SIGN].Next=First[x];
First[x]=SIGN++;
}
int Jude(int x,int y)/*查找与X是否与Y相连,是0,否1*/
{
int i;
for(i=First[x];i!=;i=ID[i].Next) //查找与该点相关的点
{
if(ID[i].TO==y)return ;
}
return ;
}
int ToPoSort(int N,int Num[])/*能够排序返回1,否则返回0*/
{/*N为点的个数(1~N),Num[]用来存储排序后的结果*/
int i,j,k;
for(j=N;j>=;j--)/*修改点一: j作为重量,重量从大到小依次赋值*/
{
for(i=N;i>=;i--)/*修改点二: i作为编号,编号从大到小查找*/
{
if(InD[i]==)/*找到符合的编号。进行赋值*/
{
InD[i]--;
Num[i]=j;/*修改点三: j作为重量,i作为编号(位置)*/
for(k=First[i];k!=;k=ID[k].Next)
{
InD[ID[k].TO]--;
}
break;
}
}
if(i<)break;/*如果全部找完,没有找到,退出*/
}
if(j<=)return ;/*如果重量能够全部赋值,既可行*/
else return ; /*反正不可行。*/
}
int main()
{
int M,N,i,T;
int Num[MAX];
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&N,&M);
int a,b;
for(i=;i<=N;i++){First[i]=;InD[i]=;}
for(i=,SIGN=;i<M;i++)
{
scanf("%d%d",&a,&b);
if(Jude(b,a)) /*判断重边*/
{
Add_E(b,a);
}
}
if(ToPoSort(N,Num))
{
for(i=;i<=N;i++)
{
if(i!=)putchar();
printf("%d",Num[i]);
}putchar();
}
else printf("-1\n");
}
return ;
} /*
4
5 4
1 4
4 2
5 3
3 2 5 3
1 4
4 2
3 5 5 4
5 1
4 2
1 3
2 3 10 5
4 1
8 1
7 8
4 1
2 8
ans:
1 5 3 4 2
1 3 4 2 5
2 4 5 3 1 逆向建图
5 1 6 2 7 8 3 4 9 10 没有判重边的话就输出 -1 */
 

Labeling Balls(变种拓扑)的更多相关文章

  1. Labeling Balls(拓扑排序wa)

    Labeling Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12466   Accepted: 3576 D ...

  2. poj 3687 Labeling Balls - 贪心 - 拓扑排序

    Windy has N balls of distinct weights from 1 unit to N units. Now he tries to label them with 1 to N ...

  3. POJ 3687 Labeling Balls(拓扑排序)题解

    Description Windy has N balls of distinct weights from 1 unit to N units. Now he tries to label them ...

  4. POJ3687 Labeling Balls(拓扑排序\贪心+Floyd)

    题目是要给n个重量1到n的球编号,有一些约束条件:编号A的球重量要小于编号B的重量,最后就是要输出字典序最小的从1到n各个编号的球的重量. 正向拓扑排序,取最小编号给最小编号是不行的,不举出个例子真的 ...

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

    题意:给出n个人,m个轻重关系,求满足给出的轻重关系的并且满足编号小的尽量在前面的序列 因为输入的是a比b重,但是我们要找的是更轻的,所以需要逆向建图 逆向建图参看的这一篇http://blog.cs ...

  6. POJ-3687 Labeling Balls(拓扑)

    不一样的拓扑排序 给定一些标记为1到n的数, 求出满足a < b 的序列, 如果有多个输出, 按先标签1往前的位置, 然后按标签2往前的位置, 对于每个标签, 位置都尽量往前. 因为位置要往前, ...

  7. POJ - 3687 Labeling Balls (拓扑)

    (点击此处查看原题) 题意 此处有n盏灯,编号为1~n,每盏灯的亮度都是唯一的,且在1~n范围之间,现已知m对灯之间的关系:a b ,说明灯a的亮度比灯b小,求出每盏灯的亮度,要求字典序最小(编号小的 ...

  8. POJ3687 Labeling Balls(拓扑)

    题目链接. 题目大意: N个球,从1-N编号,质量不同,范围1-N,无重复.给出小球间的质量关系(<), 要求给每个球贴标签,标签表示每个球的质量.按编号输出每个球的标签.如果解不唯一,按编号小 ...

  9. POJ3687——Labeling Balls(反向建图+拓扑排序)

    Labeling Balls DescriptionWindy has N balls of distinct weights from 1 unit to N units. Now he tries ...

随机推荐

  1. 流媒体:V4L2视频获取

    从深圳回来已经20多天了,除了完善毕业设计程序和论文,其他时间都去玩游戏了.真的是最后的一段时间能够无忧无虑在校园里挥霍自己的青春了.今天完成的答辩,比想象的要简单,一直以来想把我现在的这个流媒体的东 ...

  2. Win 内存映射和堆栈

    内存映射和堆栈 内存映射文件 内存映射文件可以用于3个不同的目的: 系统使用内存映射文件,以便加载和执行.exe和DLL文件.这可以大大节省页文件空间和应用程序启动运行所需的时间. 可以使用内存映射文 ...

  3. Helper Method

    ASP.NET MVC 小牛之路]13 - Helper Method 我们平时编程写一些辅助类的时候习惯用“XxxHelper”来命名.同样,在 MVC 中用于生成 Html 元素的辅助类是 Sys ...

  4. Linux环境进程间通信(二):信号(下)

    linux下进程间通信的几种主要手段: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...

  5. C#中鼠标划过按钮时候的提示信息

    ToolTip p = new ToolTip();            p.ShowAlways = true;            p.SetToolTip(this.Buton1, &quo ...

  6. ios7学习之路六(隐藏状态栏 )

    方法一(代码设置): 现在ios7已经更改为透明,并且不占用屏幕高度.其中隐藏及显示的方法如下: 在uiviewcontroller的子类下,调用:      if ([self respondsTo ...

  7. YARN之上的大数据框架REEF:微软出品,是否值得期待?

    YARN之上的大数据框架REEF:微软出品,是否值得期待?   摘要:微软即将开源大数据框架REEF,REEF运行于Hadoop新一代资源管理器YARN的上层.对于机器学习等在数据传输.任务监控和结果 ...

  8. 简单的mvc之二:蜿蜒的管线

    关于系列的第二篇,在管线与路由之间犹豫了很久,最终选择了管线—为免于盲人摸象的困惑. 管线的位置在哪里呢?webform,mvc以及web api都架构于asp.net平台上,管线则是asp.net的 ...

  9. WPF界面设计

    WPF仿360卫士9.0界面设计   Chrome插件——一键保存网页为PDF1.0 http://www.cnblogs.com/bdstjk/p/3163723.html 仿照网上的一个代码写的, ...

  10. 使用DBUnit实现对数据库的测试

    这是一个JavaProject,有关DBUnit用法详见本文测试用例 首先是用到的实体类User.java package com.jadyer.model; public class User { ...