• 【BZOJ4010】菜肴制作


    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4010


    一种比较容易想到的做法是把进行拓扑排序的队列换成优先队列,每次取出能访问到的编号最小的点,但这样是不对的,很容易构造数据卡掉。

    正确的做法是建反向图,每次取出编号最大的,再将生成的拓扑序逆序输出即可。

    第一种做法并不能保证小的编号尽量靠前,因为每次取的当前能访问到的最小的;第二种方法,相当于尽量先把编号较大的取走,实在不能取了才去取编号小的,因此逆序以后就是要求的序列。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <queue>
     5 #include <stack>
     6 
     7 using namespace std;
     8 
     9 inline int get_num() {
    10     int num = 0;
    11     char c = getchar();
    12     while (c < '0' || c > '9') c = getchar();
    13     while (c >= '0' && c <= '9')
    14         num = num * 10 + c - '0', c = getchar();
    15     return num;
    16 }
    17 
    18 const int mmax = 1e5 + 5;
    19 
    20 int head[mmax], eid;
    21 
    22 struct Edge {
    23     int v, next;
    24 } edge[mmax];
    25 
    26 inline void insert(int u, int v) {
    27     edge[++eid].v = v;
    28     edge[eid].next = head[u];
    29     head[u] = eid;
    30 }
    31 
    32 int ind[mmax];
    33 
    34 priority_queue<int> q;
    35 stack<int> ans;
    36 
    37 int main() {
    38     int d = get_num();
    39     while (d--) {
    40         int n = get_num(), m =get_num();
    41         memset(head, 0, sizeof(head));
    42         memset(ind, 0, sizeof(ind));
    43         eid = 0;
    44         for (int i = 1; i <= m; ++i) {
    45             int u = get_num(), v = get_num();
    46             insert(v, u);
    47             ++ind[u];
    48         }
    49         for (int i = 1; i <= n; ++i)
    50             if (!ind[i]) q.push(i);
    51         while (!q.empty()) {
    52             int u = q.top();
    53             q.pop();
    54             ans.push(u);
    55             for (int p = head[u]; p; p = edge[p].next) {
    56                 int v = edge[p].v;
    57                 if (!(--ind[v])) q.push(v);
    58             }
    59         }
    60         if ((int)ans.size() != n) {
    61             printf("Impossible!
    ");
    62             while (!ans.empty()) ans.pop();
    63         } else {
    64             while (!ans.empty()) {
    65                 printf("%d ", ans.top());
    66                 ans.pop();
    67             }
    68             printf("
    ");
    69         }
    70     }
    71     return 0;
    72 }
    AC代码
  • 相关阅读:
    2015.10.9js(页面坐标)
    2015.8.2js-19(完美运动框架)
    2015.7.12js-11(DOM基础)
    2015.7.7js-07-2(基础)
    2015.7.11js-10(无缝滚动)
    2015.7.10js-07(简单时间)
    2015.7.8js-05(简单日历)
    2015-7.7森林探秘季
    jquery scroll()滚动条事件
    资源(127.0.0.1)处于联机状态,但未对连接尝试做出反应
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9908971.html
Copyright © 2020-2023  润新知