HNOI2015 菜肴制作

Description


 

Input

Output

 

Sample Input

3
5 4
5 4
5 3
4 2
3 2
3 3
1 2
2 3
3 1
5 2
5 2
4 3

Sample Output

1 5 3 4 2
Impossible!
1 5 2 4 3
 

Data Constraint

 

题目本意是求一个拓扑序,使得1尽量靠前,1靠前的前提下2尽量靠前。。。

我们可以反向思考,建立反图,求字典序最大的拓扑序,然后反向输出即可

(对于一个点,我们将比它大且能放它后面的点都尽量放它后面了,这样理解一下)

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>

using namespace std;
priority_queue<int> H;

int du[100011],g[100011],next[100011],y[100011],ans[100011];
bool vis[100011];
int cnt,dt,tj,i,n,m,x,z,tt;
bool pc;

void star(int i,int j)
{
    tt++;
    next[tt]=g[i];
    g[i]=tt;
    y[tt]=j;
}

void Toplogical()
{
    int l,r,x,j,k,i;
    pc=true;
    memset(vis,false,sizeof(vis));
    for(i=1;i<=n;i++)if(du[i]==0)H.push(i);
    while(!H.empty()){
        x=H.top();
        vis[x]=true;
        H.pop();
        ans[++cnt]=x;
        j=g[x];
        while(j!=0){
            k=y[j];
            du[k]--;
            if(du[k]==0)H.push(k);
            j=next[j];
        }
    }
    for(i=1;i<=n;i++)if(!vis[i])pc=false;
}

int main()
{
    scanf("%d",&dt);
    for(tj=1;tj<=dt;tj++){
        memset(g,0,sizeof(g));
        tt=0;
        memset(du,0,sizeof(du));
        scanf("%d%d",&n,&m);
        for(i=1;i<=m;i++){
            scanf("%d%d",&x,&z);
            star(z,x);
            du[x]++;
        }
        while(!H.empty())H.pop();
        cnt=0;
        Toplogical();
        if(pc==false)printf("Impossible!
");
        else{
            for(i=cnt;i>=1;i--)printf("%d ",ans[i]);
            printf("
");
        }
    }
}
原文地址:https://www.cnblogs.com/applejxt/p/4450642.html