POJ 3687 Labeling Balls 【逆拓扑】

来源:互联网 发布:软件退税计算方法 编辑:程序博客网 时间:2024/06/11 23:39

Labeling Balls

Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 12304 Accepted: 3527

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:

  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 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, bN) 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

 

嗯,题目大意就是说,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;}


 

0 0
原创粉丝点击