POJ3687-反向拓扑排序

来源:互联网 发布:微信群加人软件免费版 编辑:程序博客网 时间:2024/05/21 11:16
/*题意为拓扑排序,使得小的结点尽可能的排在前面:如:5->6->1; 4->3->2 应让结点1尽量排在前面,再使2尽量排在前面... ...:5 6 1 4 3 2若直接按结点从小到大拓扑排序,无法得到正解:4 3 2 5 6 1反向拓扑排序,按结点从大到小的顺序这样能使结点小的尽可能的排在后面:2 3 4 1 6 5,那么反过来的5 6 1 4 3 2就是所求的拓扑序列,再编上号:5(1),6(2),1(3),4(4),3(5),2(6)即可。*/#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <vector>using namespace std;int n,m,chu[250];vector<int> adj[250];struct node{    int v;    node(){}    node(int vv):v(vv){}    bool operator<(const node a)const{        return a.v>v;    }};int s[250],lab[250],cnt;bool solve(void){    priority_queue<node> q;    for (int i=1; i<=n; i++) if (!chu[i]) q.push(node(i));    if (q.empty()) return false;    cnt=0;    while (!q.empty())    {        int u=q.top().v;        q.pop();        s[cnt++]=u;        for (int i=0; i<adj[u].size(); i++)        {            int v=adj[u][i];            if (--chu[v]==0) q.push(node(v));        }    }    if (cnt<n) return false;    for (int i=0; i<cnt; i++) lab[s[i]]=n-i;    printf("%d",lab[1]);    for (int i=2; i<=n; i++) printf(" %d",lab[i]);    printf("\n");    return true;}int main(){    int cas;    scanf("%d",&cas);    while (cas--)    {        scanf("%d%d",&n,&m);        for (int i=1; i<=n; i++)        {            chu[i]=0;            adj[i].clear();        }        int x,y;        for (int i=1; i<=m; i++)        {            scanf("%d%d",&x,&y);            adj[y].push_back(x);            chu[x]++;        }        if (!solve()) printf("-1\n");    }    return 0;}