[poj3687]拓扑排序的应用

来源:互联网 发布:混迹知乎的浩天哥 编辑:程序博客网 时间:2024/04/30 06:52

题目描述

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?

算法思路

  1. 纯粹为了输出字典序想了很长时间,WA了很多次,最后终于想通了。
  2. 其实使用堆的算法可以看作一个贪心算法,因为每次取的元素都是当前最优先的元素,所以着重要看它们的最优子结构和贪心选择的性质。
  3. 如果我们正向拓扑,那么显然我们期望越小的标号被越早的选中,所以我们会用小顶堆,但是,此时不一定可以得到字典序,因为如果一个很大的元素在1的前面,就可以造成错误。
  4. 所以,我们逆向拓扑,构造大顶堆,此时我们期望标号越小的点被越晚的选中,很显然此时可以成立。
  5. 还有,图中会有重边,注意判断。

代码

#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<algorithm>#include<queue>using namespace std;#define MAXN 203#define INF 0x3f3f3f3fint n,m,t;int grid[MAXN][MAXN];int indeg[MAXN];void Solve(){    int i;    int a[MAXN];    int ans[MAXN];    int Count = 0;    priority_queue<int,vector<int>,less<int> >Q;    for(i=1;i<=n;i++){        if(!indeg[i]){            Q.push(i);            indeg[i] = -1;        }    }    while(!Q.empty()){        int cur = Q.top();        Q.pop();        a[++Count]=cur;        for(i=1;i<=n;i++){            if(grid[cur][i]){                indeg[i]--;                if(!indeg[i]){                    indeg[i] = -1;                    Q.push(i);                }            }        }    }    if(Count<n)        printf("-1\n");    else{        for(i=1;i<=n;i++)            ans[a[n-i+1]]=i;        printf("%d",ans[1]);        for(i=2;i<=n;i++)            printf(" %d",ans[i]);        printf("\n");    }    return;}int main(){    freopen("input","r",stdin);    int i,tmp1,tmp2;    scanf("%d",&t);    while(t--){        memset(indeg,0,sizeof(indeg));        memset(grid,0,sizeof(grid));        scanf("%d%d",&n,&m);        for(i=0;i<m;i++){            scanf("%d%d",&tmp1,&tmp2);                if(!grid[tmp2][tmp1]){                grid[tmp2][tmp1]=1;                indeg[tmp1]++;            }        }        Solve();    }    return 0;}
0 0
原创粉丝点击