POJ3687Labeling Balls 解题思路加感受
来源:互联网 发布:ssh连接阿里云 编辑:程序博客网 时间:2024/06/16 09:13
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 the same label.
- The labeling satisfies several constrains like "The ball labeled with a is lighter than the one labeled withb".
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 nextM line each contain two integers a and b indicating the ball labeled witha 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 labelN. 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
54 04 11 14 21 22 14 12 14 13 2
Sample Output
1 2 3 4-1-12 1 3 41 3 2 4
Source
题目大意:首先对N个质量分别为1,2,~N的球进行编号为1,2,~N,然后对某些编号的球的质量会有要求,比如:3 2,这就要求序号为3的球的质量必须小于序号为2的球,在这样的要求下可能会有多种排序方式,但没有涉及的一些球之间也要满足序号小的球的质量要小于序号大的球的质量,比如上面第五个样例中给出的 n=4,m=1,3 2 代表序号为3的球的质量要小于序号为2的球,最终答案时1 3 2 4,而不是3 2 1 4或者 2 4 3 1 等等,,此道题目利用拓扑进行逆序建图会方便不少。
上代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stack>
using namespace std;
int map[210][210],in[210],out[210],vis[210];
int n,m;
int tp[210];
int topo()
{
stack<int >s;
int num,num1,i,j;
for(i=1,num=0; i<=n; i++) // 该for循环最后得到有要求的点的数目
{
if(vis[i]==1)
{
num++;
}
}
num1=0;
for(i=1;i<=n;i++) //开始判断有木有环 在这里额wa了n次
{
if(vis[i]==1&&in[i]==0) s.push(i);
}
while(!s.empty())
{
int x=s.top();
s.pop();
num1++;
for(i=1;i<=n;i++)
{
if(map[x][i])
{
in[i]--;
if(in[i]==0)
s.push(i);
}
}
}
if(num1!=num) //有环输出-1
{
printf("-1\n");
return 0;
}
num=n;
memset(tp,0,sizeof(tp));
while(1)
{
for(i=n; i>0; i--)
{
if(tp[i]==0&&out[i]==0) //依据编号从大到小进行安排
break;
}
if(i==0) break;
tp[i]=num--;
for(j=1; j<=n; j++)
{
if(map[j][i]==1)
out[j]--;
}
}
for(i=1; i<=n; i++)
{
if(i!=n) printf("%d ",tp[i]);
else printf("%d\n",tp[i]);
}
return 0;
}
int main()
{
int T,s,e,i;
scanf("%d",&T);
while(T--)
{
memset(map,0,sizeof(map));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(vis,0,sizeof(vis));
scanf("%d %d",&n,&m);
if(m==0)
{
for(i=1; i<=n; i++)
{
if(i!=n)
printf("%d ",i);
else printf("%d\n",i);
}
}
else
{
for(i=1; i<=m; i++)
{
scanf("%d %d",&s,&e);
if(map[s][e]==0) //记得要判断重边
{
map[s][e]=1;
in[e]++;
out[s]++;
vis[s]=vis[e]=1; //对有要求的点做个记号
}
}
topo(); //here we go topo
}
}
return 0;
}
- POJ3687Labeling Balls 解题思路加感受
- poj3687Labeling Balls(逆序拓扑)
- POJ3687Labeling Balls(拓扑排序)
- poj3687Labeling Balls(反向拓扑+优先队列)
- poj3687Labeling Balls【反向拓扑排序 模板】
- 解题思路
- 解题思路
- 解题思路
- 解题思路
- 解题思路
- codeforces上解题感受
- HDU 4611 Balls Rearrangement 解题报告
- HDOJ-3635-Dragon Balls 解题报告
- 【Jason's_ACM_解题报告】Dropping Balls
- 【ACM菜逼解题报告】Dropping Balls
- HDOJ-5194-DZY Loves Balls 解题报告
- 话说解题思路
- 话说解题思路
- POJ题目分类
- 由poj 1067引发的——取石子游…
- 如何写出很牛的代码,提高你的代码…
- 威佐夫博弈、黄金分割、POJ 1067
- java提高篇(十七)-----异常(二)
- POJ3687Labeling Balls 解题思路加感受
- swap函数
- HDOJ 1262 寻找素数对
- 几点建议,让Redis在你的系统中发挥更大作用
- HDOJ 1597 find the nth digit
- HDOJ 4342 History repeat itse…
- Lucas定理 && HODJ 4349
- HDOJ 4341 Gold miner[条件背包]
- KMP字符串模式匹配详解