您的位置:首页 > 其它

poj3687Labeling Balls【反向拓扑排序 模板】

2016-02-03 15:55 405 查看
Labeling Balls

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 12994 Accepted: 3748
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


折腾了将近两个小时总算在discuess的只言片语中知道自己错在哪里了,怎么说也是没参考别人代码A的,但是思维严谨性啊……自己写测试数据!自己好好读题!

1.题中有一句特别坑爹的话:For each test case output on a single line the balls' weights from label 1 to labelN. 输出的是这个数字所在的位置 ,不是这个位置上的数字

2.反向输出!这个写几组数据就能看出来吧。但是为什么呢?因为如果只是限制优先级,小的数先输出,有可能得不到正解,反向输出,大的放到后面就解决了这个问题

/****************
poj3687
2016.2.3
916K	79MS	G++	1939B
****************/
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include<vector>
using namespace std;
const int maxn=300;
int tmp[400];
bool mark[205][205];
int head[maxn],ip,indegree[maxn];
int t,n,m,seq[maxn];
struct cmp1{
bool operator ()(int &a,int &b){
return a<b;//最大值优先
}
};
struct note
{
int v,next;
} edge[maxn*maxn];

void init()
{
memset(head,-1,sizeof(head));
ip=0;
memset(indegree,0,sizeof(indegree));
memset(mark,0,sizeof(mark));
}

void addedge(int u,int v)
{
edge[ip].v=v,edge[ip].next=head[u],head[u]=ip++;
}

int topo()///拓扑,可做模板
{
priority_queue<int,vector<int>,cmp1>que1;
int indeg[maxn];
for(int i=1; i<=n; i++)
{
indeg[i]=indegree[i];
if(indeg[i]==0)
que1.push(i);
}
int k=n;
bool res=false;
while(!que1.empty())
{
if(que1.size()!=1)res=true;
int u=que1.top();
que1.pop();
seq[k--]=u;
for(int i=head[u]; i!=-1; i=edge[i].next)
{
int v=edge[i].v;
indeg[v]--;
if(indeg[v]==0)
que1.push(v);
}
}
if(k>0)return -1;///存在有向环,总之不能进行拓扑排序
if(res)return 0;///可以进行拓扑排序,并且只有唯一一种方式,seq数组即是排序完好的序列
return 1;///可以进行拓扑排序,有多种情况,seq数组是其中一种序列
}

int main()
{
、、freopen("cin.txt","r",stdin);
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
while(m--)
{
int a,b;
scanf("%d%d",&a,&b);
if(mark[a][b]) continue;
addedge(b,a);
indegree[a]++;
mark[a][b]=1;
}
if(topo()==-1) printf("-1\n");
else
{
for(int i=1;i<=n;i++) tmp[seq[i]]=i;
for(int i=1;i<n;i++) printf("%d ",tmp[i]);
printf("%d\n",tmp
);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: