您的位置:首页 > 其它

POJ 3687 Labeling Balls 【逆拓扑】

2015-08-19 10:14 411 查看

Labeling Balls

Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 12304Accepted: 3527
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 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


嗯,题目大意就是说,n个气球重量为1到n,现在要贴标签也是1到n,然后下面是m个要求例如a b,表示标号为a的球要比标号为b的球轻,然后输出的是从1号到n号所对应的球的重量。拓扑排序时要求当排序不唯一时要让标号小的重量也小,这里我用逆拓扑和优先队列,正常情况让输出所排的标签的顺序时要逆序输出,这里我是先让数组反转,之后在通过标号找重量,按标号从小到大输出重量。嗯,我做的比较麻烦,不造别人怎么做的。。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int n,in[220],ans[220],rec[220],map[220][220];
void top_sort()
{
int k=0;
priority_queue<int>q;
for(int i=1;i<=n;++i)
{
if(in[i]==0)
{
q.push(i);
in[i]--;
}
}
while(!q.empty())
{
int u=q.top();
rec[k++]=u;
q.pop();
for(int i=1;i<=n;++i)
{
if(map[u][i])
{
in[i]--;
if(in[i]==0)
{
q.push(i);
in[i]--;
}
}
}
}
if(k<n)
printf("-1\n");
else
{
int i,j;
for(i=k-1,j=0;i>=0;i--)
ans[++j]=rec[i];
/*memset(rec,0,sizeof(rec));
for(i=1;i<=k;++i)//这里找到与原先数组刚好那什么的数组再输出,嗯,就是例如a[2]=4,那么我所找的数组就是b[4]=2
rec[ans[i]]=i;
for(int i=1;i<=k;++i)
{
if(i==1)
printf("%d",rec[i]);
else
printf(" %d",rec[i]);
}*/
for(i=1;i<=k;++i)//这里直接按标号找重量
{
for(j=1;j<=k;++j)
{
if(ans[j]==i)
{
if(i==1)
printf("%d",j);
else
printf(" %d",j);
break;
}
}
}
printf("\n");
}
}
int main()
{
int t,m,a,b;
scanf("%d",&t);
while(t--)
{
memset(in,0,sizeof(in));
memset(map,0,sizeof(map));
scanf("%d%d",&n,&m);
while(m--)
{
scanf("%d%d",&a,&b);
if(!map[b][a])
{
map[b][a]=1;
in[a]++;
}
}
top_sort();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: