POJ 3687 (拓扑排序,逆序,优先队列)

来源:互联网 发布:asp交友源码 编辑:程序博客网 时间:2024/06/03 14:17

题目:http://poj.org/problem?id=3687

是一个练习字典序输出,拓扑排序的好题,但考察的数据太没意思。

输出的是位置而不是序列本身。。。

大意:给了约束,a>b,其余按字典序输出。

/*优先队列。*/#include<cstdio>#include<cstring>#include<iostream>#include<queue>using namespace std;const int maxn=205;int in[maxn],sum,n,m,ans[maxn];bool visit[maxn][maxn];vector<int > G[maxn];void init(){    memset(G,0,sizeof(G));    memset(in,0,sizeof(in));    memset(ans,0,sizeof(ans));    memset(visit,0,sizeof(visit));    sum=n;}void toposort(){    priority_queue<int>s;    int cnt=n;    for(int i=1;i<=n;i++){  //注意是从0开始还是从1开始        if(in[i]==0)      //收入入度为0的点        s.push(i);    }    while(!s.empty()){ //由于互为环的点的入度是不会为0的,所以不会被push进来        int pos=s.top();        s.pop(),sum--;        ans[pos]=cnt--;        for(int i=0;i<G[pos].size();i++){            in[G[pos][i]]--;       //与pos相连的点入度减一            if(in[G[pos][i]]==0)                s.push(G[pos][i]); //收入新一波入度为0的点        }    }    if(sum>0) printf("-1\n");   //有环,sum无法--    else{        for(int i=1;i<n;i++)            printf("%d ",ans[i]);        printf("%d\n",ans[n]);    }}int main(){    int num;    scanf("%d",&num);    while(num--){        scanf("%d%d",&n,&m);        init();        int x,y;        for(int i=0;i<m;i++){            scanf("%d%d",&x,&y);            if(visit[x][y]==true)                continue;            G[y].push_back(x);            in[x]++;            visit[x][y]=true;        }        toposort();    }    return 0;}


阅读全文
0 0