zoukankan      html  css  js  c++  java
  • bzoj4010: [HNOI2015]菜肴制作【拓扑排序】

      想到了一个分治方法,每一次尽量放小的那个,把它依赖的放在左边,不依赖的放在右边。

      TLE 80:

     1 #include <bits/stdc++.h>
     2 #define rep(i, a, b) for (int i = a; i <= b; i++)
     3 #define drep(i, a, b) for (int i = a; i >= b; i--)
     4 #define REP(i, a, b) for (int i = a; i < b; i++)
     5 #define mp make_pair
     6 #define pb push_back
     7 #define clr(x) memset(x, 0, sizeof(x))
     8 #define xx first
     9 #define yy second
    10 using namespace std;
    11 typedef long long i64;
    12 typedef pair<int, int> pii;
    13 const int inf = ~0U >> 1;
    14 const i64 INF = ~0ULL >> 1;
    15 //***********************************
    16 
    17 const int maxn = 100005;
    18 
    19 vector <int> Vx[maxn], Vy[maxn];
    20 int src[maxn], lft[maxn];
    21 
    22 int n, m;
    23 int deg[maxn], tmp[maxn];
    24 
    25 bool topo() {
    26     static int que[maxn]; int qh(0), qt(0);
    27     rep(i, 1, n) if (!deg[i]) que[++qt] = i;
    28     int cnt(0);
    29     while (qh != qt) {
    30         int x = que[++qh];
    31         ++cnt;
    32         int len = (int) Vx[x].size();
    33         for (int i = 0; i < len; i++) {
    34             if (--deg[Vx[x][i]] == 0) que[++qt] = Vx[x][i];
    35         }
    36     }
    37     return cnt == n;
    38 }
    39 
    40 bool vis[maxn];
    41 void bfs(int s) {
    42     static int que[maxn]; int qh(0), qt(0);
    43     vis[que[++qt] = s] = 1;
    44     while (qh != qt) {
    45         int x = que[++qh];
    46         int len = (int) Vy[x].size();
    47         for (int i = 0; i < len; i++) {
    48             if (!vis[Vy[x][i]]) {
    49                 vis[que[++qt] = Vy[x][i]] = 1;
    50                 lft[Vy[x][i]] = 1;
    51             }
    52         }
    53     }
    54 }
    55 
    56 void solve(int l, int r) {
    57     if (l >= r) return;
    58     int t, haha = inf;
    59     rep(i, l, r) if (src[i] < haha) { t = i; haha = src[i]; }
    60     rep(i, l, r) lft[src[i]] = vis[src[i]] = 0;
    61     bfs(src[t]);
    62     int cur = l - 1;
    63     rep(i, l, r) if (src[i] != src[t] && lft[src[i]]) tmp[++cur] = src[i];
    64     tmp[++cur] = src[t]; int mid = cur;
    65     rep(i, l, r) if (src[i] != src[t] && !lft[src[i]]) tmp[++cur] = src[i];
    66     memcpy(src + l, tmp + l, sizeof(int) * (r - l + 1));
    67     solve(l, mid - 1);
    68     solve(mid + 1, r);
    69 }
    70 
    71 int main() {
    72     freopen("dishes.in", "r", stdin);
    73     freopen("dishes.out", "w", stdout);
    74     int T; scanf("%d", &T);
    75     while (T--) {
    76         scanf("%d%d", &n, &m);
    77         rep(i, 1, n) Vx[i].clear(), Vy[i].clear();
    78         clr(deg);
    79         rep(i, 1, m) {
    80             int x, y; scanf("%d%d", &x, &y);
    81             Vx[x].pb(y);
    82             Vy[y].pb(x);
    83             deg[y]++;
    84         }
    85         if (!topo()) { puts("Impossible!"); continue; }
    86         rep(i, 1, n) src[i] = i;
    87         solve(1, n);
    88         rep(i, 1, n) printf(i == n ? "%d
    " : "%d ", src[i]);
    89     }
    90     return 0;
    91 }
    View Code

      正解:

        有依赖关系,我们建立反图,加入我们的到了这个反图的一个拓扑序,那么怎样对应到最优的答案呢?应该是尽量让编号小的出现在队列后方,所以最大字典序的拓扑排序即可。

     1 #include <bits/stdc++.h>
     2 #define rep(i, a, b) for (int i = a; i <= b; i++)
     3 #define drep(i, a, b) for (int i = a; i >= b; i--)
     4 #define REP(i, a, b) for (int i = a; i < b; i++)
     5 #define mp make_pair
     6 #define pb push_back
     7 #define clr(x) memset(x, 0, sizeof(x))
     8 #define xx first
     9 #define yy second
    10 using namespace std;
    11 typedef long long i64;
    12 typedef pair<int, int> pii;
    13 const int inf = ~0U >> 1;
    14 const i64 INF = ~0ULL >> 1;
    15 //***********************************
    16 
    17 const int maxn = 100005;
    18 
    19 vector <int> Vx[maxn], Vy[maxn];
    20 priority_queue<int> Q;
    21 int deg[maxn], ans[maxn], n, m;
    22 
    23 bool topo() {
    24     rep(i, 1, n) if (!deg[i]) Q.push(i);
    25     int cnt(0);
    26     while (!Q.empty()) {
    27         int x = Q.top(); Q.pop();
    28         ans[++cnt] = x;
    29         int len = (int) Vy[x].size();
    30         for (int i = 0; i < len; i++) {
    31             if (--deg[Vy[x][i]] == 0) Q.push(Vy[x][i]);
    32         }
    33     }
    34     return cnt == n;
    35 }
    36 
    37 int main() {
    38     freopen("dishes.in", "r", stdin);
    39     freopen("dishes.out", "w", stdout);
    40     int T; scanf("%d", &T);
    41     while (T--) {
    42         scanf("%d%d", &n, &m);
    43         rep(i, 1, n) Vx[i].clear(), Vy[i].clear();
    44         clr(deg);
    45         rep(i, 1, m) {
    46             int x, y; scanf("%d%d", &x, &y);
    47             Vx[x].pb(y);
    48             Vy[y].pb(x);
    49             deg[x]++;
    50         }
    51         if (!topo()) puts("Impossible!");
    52         else { drep(i, n, 1) printf("%d ", ans[i]); puts(""); }
    53     }
    54     return 0;
    55 }
    View Code
  • 相关阅读:
    DevOps实施方法论,为什么大企业一定要使用DevOps?
    SpringCloudAlibaba基础入门,基于Nacos构建分布式与配置,Sentinel服务治理
    艾编程Java进阶架构师必看:15次架构演进详解
    实战笔记:来一起探究下Kafka是如何实现万亿级海量数据的高并发写入的?
    520疯狂之后我彻底蒙了,老板让我做技术选型,数据处理选kafka还是RocketMQ?
    如何实现Redis数据持久化以及内存管理之缓存过期机制
    SpringBoot源码深度解析
    分布式缓存Redis高级应用实战:为什么要用缓存机制
    全面上云实战教程:基于阿里云安装配置部署docker详解
    Solr学习笔记(2)—— solr-7.0.0 安装与目录说明
  • 原文地址:https://www.cnblogs.com/y7070/p/5090100.html
Copyright © 2011-2022 走看看