• P3243 [HNOI2015]菜肴制作


    题意

    这题上来很容易想去求最小的拓扑序,即将队列换成堆的做法。

    然而题目要求小的数尽量靠前,我们就拿样例的第三个说:

    字典序最小:(14352)

    正解:(15243)

    因为正解中(2)比字典序最小拓扑序的更靠前((3<5))。

    也就说越小的数越应该在前面,之后再考虑其他的数,那么正着不好想不妨反过来:越大的数越应该靠后。

    于是建反图求字典序最大的拓朴序,之后反着输出即可。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=100010;
    struct edge
    {
        int to,nxt;
    }e[maxn];
    int T,n,m,cnt,tot;
    int head[maxn],deg[maxn],a[maxn];
    inline void add(int u,int v)
    {
        e[++cnt].nxt=head[u];
        head[u]=cnt;
        e[cnt].to=v;deg[v]++;
    }
    void init()
    {
        memset(head,0,sizeof(head));
        memset(deg,0,sizeof(deg));
        cnt=tot=0;
    }
    void topsort()
    {
        priority_queue<int> q;
        for(int i=1;i<=n;i++) if(!deg[i]) q.push(i);
        while(!q.empty())
        {
            int x=q.top();q.pop();a[++tot]=x;
            for(int i=head[x];i;i=e[i].nxt)
            {
                int y=e[i].to;deg[y]--;
                if(!deg[y]) q.push(y);
            }
        }
        if(tot<n) printf("Impossible!");
        else for(int i=tot;i;i--) printf("%d ",a[i]);
        puts("");
    }
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            init();
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++) 
            {
                int u,v;scanf("%d%d",&u,&v);
                add(v,u);
            }
            topsort();
        }
        return 0;
    }
    
  • 相关阅读:
    BOM和DOM的操作
    JS介绍
    CSS
    HTML的用法
    JSP获取json格式的数据报错 Uncaught SyntaxError: Unexpected identifier
    jquery.nicescroll.min.js滚动条插件的用法
    css鼠标滑过出现文字效果
    sublime text3安装js提示的插件
    利用after和before伪元素在文字两边写横线
    html+css居中问题
  • 原文地址:https://www.cnblogs.com/nofind/p/12077777.html
Copyright © 2020-2023  润新知