• 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
  • 相关阅读:
    django第10天(聚合查询,常用字段)
    django第9天(多表操作)
    django第8天(在测试文件中运行django项目|单表操作)
    django第七天(模板的复用性,include标签和母版)
    django第六天(模板相关,过滤器和标记)
    SparkCore2
    SparkCore
    SQL
    Spark基础
    使用Observer实现HBase到Elasticsearch的数据同步
  • 原文地址:https://www.cnblogs.com/y7070/p/5090100.html
Copyright © 2020-2023  润新知