zoukankan      html  css  js  c++  java
  • [HNOI2015]菜肴制作

    洛咕

    题意:给定(m)个有序对((a,b)),构造一个(n)的排列,满足(m)个有序对中(a)均排在(b)的前面,且1尽量靠前,在1尽量靠前的前提下,2尽量靠前,....以此类推.(n,m<=100000.)

    分析:结论题???还是不会证结论的那种.

    首先一个合法的排列就是反向图的拓扑序,然后是要让(1,2...)尽量靠前,那么就是反向图的拓扑序的字典序尽量大,这个我们直接开一个大根堆维护点的编号就好了.

    具体说来,反向建图,然后把度数为0的点丢进大根堆里跑拓扑排序即可.如果跑完拓扑之后的排列里面没有n个数,判断无解,否则倒序输出就是答案了.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=100005;
    int deg[N],Ans[N];
    int tot,head[N],nxt[N],to[N];
    priority_queue<int>q;
    inline void add(int a,int b){
    	nxt[++tot]=head[a];head[a]=tot;to[tot]=b;
    }
    int main(){
    	int T=read();
    	while(T--){
    		tot=0;memset(head,0,sizeof(head));
    		memset(deg,0,sizeof(deg));
    		int n=read(),m=read();
    		for(int i=1;i<=m;++i){
    			int a=read(),b=read();
    			add(b,a);++deg[a];
    		}
    		for(int i=1;i<=n;++i)if(!deg[i])q.push(i);
    		int ans=0;
    		while(q.size()){
    			int u=q.top();q.pop();
    			Ans[++ans]=u;
    			for(int i=head[u];i;i=nxt[i]){
    				int v=to[i];--deg[v];
    				if(!deg[v])q.push(v);
    			}
    		}
    		if(ans!=n)puts("Impossible!");
    		else{
    			for(int i=ans;i>=1;--i)
    				printf("%d ",Ans[i]);
    			printf("
    ");
    		}
    	}
        return 0;
    }
    
    
  • 相关阅读:
    ABAP ole方式对EXCEL进行操作
    ABAP 通过视图取数到内表函数
    ABAP 数值类型转换
    ABAP 供应商、工厂对应公里数维护
    deb包转换为rpm包格式
    Linux统计即时网速
    RedHat可用的几处软件源
    linux 技巧:使用 screen 管理你的远程会话
    国内常用Linux镜像站点
    telnet访问出现telnet:Unable to connect to remote host: No route to host
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11543854.html
Copyright © 2011-2022 走看看