【巧妙拓扑排序】poj 3687

来源:互联网 发布:淘宝直播视频怎么删除 编辑:程序博客网 时间:2024/05/21 10:07

这题网上大多建议反向topsort,不过也可以正向的,只是记录的不是入度,而是出度!利用优先队列每次取出label大的,下标从n往前记录。注意:我代码ans求出的只是1~n重量对应的标签,题目中有For each test case output on a single line the balls' weights from label 1 to label N.所以还要转化为重量从1~n所对应的标签;还有,注意重边!

#include <vector>#include <list>#include <map>#include <set>#include <queue>#include <string.h>#include <deque>#include <stack>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iostream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <limits.h>using namespace std;int lowbit(int t){return t&(-t);}int countbit(int t){return (t==0)?0:(1+countbit(t&(t-1)));}int gcd(int a,int b){return (b==0)?a:gcd(b,a%b);}#define LL long long#define PI acos(-1.0)#define N  1000010#define MAX INT_MAX#define MIN INT_MIN#define eps 1e-8#define FRE freopen("a.txt","r",stdin)int g[201][201];int out[201];int n,m;int ans[201];int w[201];priority_queue<int> q;void topsort(){    int i,j,k;    while(!q.empty())q.pop();    memset(out,0,sizeof(out));    for(i=1;i<=n;i++)//防止重边!!!    for(j=1;j<=n;j++)    if(g[i][j])out[i]++;    for(i=1;i<=n;i++)    if(!out[i])    q.push(i);    int cnt=n;    while(!q.empty()){        int x=q.top();        q.pop();        ans[cnt--]=x;        for(i=1;i<=n;i++){            if(g[i][x])            {out[i]--;            if(out[i]==0)            {out[i]=-1;q.push(i);}            }        }    }    if(cnt>0)printf("-1\n");    else{        //for(i=1;i<n;i++)printf("%d ",ans[i]);        //printf("%d\n",ans[n]);        for(i=1;i<=n;i++)//注意:ans求出的只是1~n重量对应的标签,题目中For each test case output on a single line the balls' weights from label 1 to label N.所以还要转化为重量从1~n所对应的标签        w[ans[i]]=i;        for(i=1;i<n;i++)        printf("%d ",w[i]);        printf("%d\n",w[n]);    }}int main(){    int ca;    scanf("%d",&ca);    while(ca--){        int i,j,k;        scanf("%d%d",&n,&m);        memset(g,0,sizeof(g));        while(m--){            int a,b;            scanf("%d%d",&a,&b);            g[a][b]=1;            //out[a]++;不能这样!要防止重边        }        topsort();    }    return 0;}


原创粉丝点击