• Luogu P3243 [HNOI2015]菜肴制作


    传送门

    这道题的正解贪心思路我看了题解....

    给出点对的先后次序,很容易想到拓扑排序。

    但是如果按字典序排序,就会遇到较小的就放在前面,

    可以举出反例:4种菜肴,限制为<2,4><3,1>,

    那么字典序最小的是2,3,1,4,但正解应为3,1,2,4.

    因为按字典序排序只能按前一个点排,不能知道后一个点的大小。

    通过观察发现,想让最小的尽早出现,就是要让较大的尽可能晚出现。

    而可以放在后面的点是确定的。

    那么反向连边,最后输出拓扑的倒序即可。

    注意,不满足条件的情况除了开始就没有入度为0的点外,还有可能有部分几个点形成闭环。

    所以最后要判断排出顺序的点数是否与总点数相等。

    代码如下

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #define MogeKo qwq
    #include<queue>
    using namespace std;
    const int maxn = 1e5+10;
    int t,n,m,x,y,cnt,num;
    int a[maxn],inn[maxn];
    int head[maxn],to[maxn],nxt[maxn];
    
    void add(int x,int y) {
        to[++cnt] = y;
        nxt[cnt] = head[x];
        head[x] = cnt;
    }
    
    void init() {
        cnt = num = 0;
        memset(head,0,sizeof(head));
        memset(to,0,sizeof(to));
        memset(nxt,0,sizeof(nxt));
        memset(inn,0,sizeof(inn));
    }
    
    void topo() {
        priority_queue <int> q;
        for(int i = 1; i <= n; i++)
            if(!inn[i]) q.push(i);
        if(q.empty()) {
            printf("Impossible!
    ");
            return;
        }
        while(!q.empty()) {
            int u = q.top();
            q.pop();
            a[++num] = u;
            if(!head[u]) continue;
            for(int i = head[u]; i; i = nxt[i]) {
                int v = to[i];
                inn[v]--;
                if(inn[v] == 0) q.push(v);
            }
        }
        if(num < n) {
            printf("Impossible!
    ");
            return;
        }
        for(int i = n; i >= 1; i--)
            printf("%d ",a[i]);
        printf("
    ");
    }
    
    int main() {
        scanf("%d",&t);
        while(t--) {
            init();
            scanf("%d%d",&n,&m);
            for(int i = 1; i <= m; i++) {
                scanf("%d%d",&x,&y);
                add(y,x);
                inn[x]++;
            }
            topo();
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Cookie 干货
    element-ui 框架中使用 NavMenu 导航菜单组件时,点击一个子菜单会出现多个子菜单同时展开或折叠?
    数组遍历的方法
    前端网页字体
    样式小收藏:完成、错误、提示动态图标样式
    多语言网站利器 rel="alternate" hreflang="x"
    网页中文章显示一部分,然后“查看全文”
    仿水滴筹中快捷留言祝福、随机生成祝福
    TypeScript知识点
    前端项目经验
  • 原文地址:https://www.cnblogs.com/mogeko/p/10934864.html
Copyright © 2020-2023  润新知