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 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和M,N表示有N个小球,编号分别为1—N。M表示下面用M组数据(x,y)。
数据(x,y)表示小球x比小球y轻。每个小球的重量都不同,且范围是[1,n]。
输出为 编号1的小球的重量,编号2小球的重量。。。编号N小球的重量(且使编号小的小球尽量轻)。条件矛盾的话输出-1。
解题思路:
错误思路:正向建图+拓扑排序+贪心查找最小的编号 在根据编号在拓扑数组中的位置输出。(正向的贪心不能完全保证序号小的节点尽量排在前面。??)
eg:6→1→3←5←4←2
1)查找到6和2 将2加入topo数组
2)查找到6和4 将4加入topo数组
3)查找到6和5 将5加入topo数组
4)将6加入数组 将1加入数组 将3加入数组
topo数组:2 4 5 6 1 3
输出为:5 1 6 2 3 4
正确思路:反向建图+拓扑排序(尽量保证编号大的小球先确定大的重量)
eg:6→1→3←5←4←2 反向之后:6←1←3→5→4→2
1)查找到3 将3加入topo数组
2)查找到5 将5加入topo数组
3)查找到4 将4加入topo数组
4)将2加入数组 将1加入数组 将6加入数组
topo数组:6 1 2 4 5 3
输出为: 2 3 6 4 5 1
Code:
#include<stdio.h>
#include<string>
#include<iostream>
#include<cstring>
#define MAXN 300
using namespace std;
int topo[MAXN+],map[MAXN+][MAXN+],dis[MAXN+];
bool vis[MAXN+];
int main()
{
int T,N,M;
cin>>T;
while (T--)
{
memset(vis,,sizeof(vis));
memset(dis,,sizeof(dis));
memset(topo,,sizeof(topo));
memset(map,,sizeof(map));
bool ok=;
cin>>N>>M;
int i,j;
for (i=; i<=M; i++)
{
int t1,t2;
cin>>t1>>t2;
if (!map[t2][t1]) dis[t1]++;
map[t2][t1]=;
}
for (i=N; i>=; i--)
{
for (j=N; j>=; j--)
if (!dis[j]&&!vis[j])
{
topo[i]=j;
vis[j]=;
break;
}
if (j==) ok=;
for (int k=; k<=N;k++)
if (map[j][k])
dis[k]--;
}
if (ok)
{
for (i=; i<=N; i++)
{
//printf("%d",topo[i]);
for (int j=; j<=N; j++)
{
if (topo[j]==i)
printf("%d",j);
}
if (i==N) printf("\n");
else printf(" ");
}
}
else printf("-1\n");
}
return ;
}