• BZOJ 4016: [FJOI2014]最短路径树问题


    建最短路树的时候,优先队列加一条限制,当花费相同的时候id小的排前面

    这样建出来的最短路树就是符合题意的

    再考虑点分治

    因为不满足前缀加减性,那么考虑按序遍历即可

    考虑如何同时维护最大值及其个数

    判断当前值是大于还是等于已经存的值

    如果大于 替换掉,次数置为1

    如果等于 次数++

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define INF 0x3f3f3f3f
      5 #define N 60010
      6 #define pii pair <int, int>
      7 int n, m, k;
      8 struct Graph
      9 {
     10     struct node
     11     {
     12         int to, nx, w;
     13         node() {}
     14         node(int to, int nx, int w) : to(to), nx(nx), w(w) {}
     15     }a[N << 1];
     16     int head[N], pos;
     17     void init()
     18     {
     19         memset(head, 0, sizeof head);
     20         pos = 0;
     21     }
     22     void add(int u, int v, int w)
     23     {
     24         a[++pos] = node(v, head[u], w); head[u] = pos;
     25         a[++pos] = node(u, head[v], w); head[v] = pos;
     26     }
     27 }G[2];
     28 #define erp(G, u) for (int it = G.head[u], v = G.a[it].to, w = G.a[it].w; it; it = G.a[it].nx, v = G.a[it].to, w = G.a[it].w)
     29 
     30 struct node
     31 {
     32     int u, w, fa, v;
     33     node() {}
     34     node(int u, int w, int fa, int v) : u(u), w(w), fa(fa), v(v) {}
     35     bool operator < (const node &other) const
     36     {
     37         if (w != other.w) return w > other.w;
     38         return u > other.u; 
     39     }
     40 };
     41 int dist[N], used[N];
     42 void Dijkstra()
     43 {
     44     for (int i = 1; i <= n; ++i) dist[i] = INF, used[i] = false;
     45     dist[1] = 0; priority_queue <node> q; q.push(node(1, 0, -1, 0));
     46     while (!q.empty())
     47     {
     48         int u = q.top().u;
     49         if (used[u])
     50         {
     51             q.pop();
     52             continue;
     53         }
     54         if (u != 1)
     55             G[1].add(q.top().fa, u, q.top().v);
     56         q.pop();
     57         used[u] = true;
     58         erp(G[0], u) if (!used[v] && dist[v] > dist[u] + w)
     59         {
     60             dist[v] = dist[u] + w;
     61             q.push(node(v, dist[v], u, w));
     62         }
     63     }
     64 }
     65 
     66 int vis[N];
     67 int sum, root, sze[N], f[N];
     68 void getroot(int u, int fa)
     69 {
     70     f[u] = 0, sze[u] = 1;
     71     erp(G[1], u) if (v != fa && !vis[v])
     72     {
     73         getroot(v, u);
     74         sze[u] += sze[v];
     75         f[u] = max(f[u], sze[v]);
     76     }
     77     f[u] = max(f[u], sum - sze[u]);
     78     if (f[u] < f[root]) root = u;
     79 }  
     80 
     81 int deep[N], res[2]; pii t[N]; 
     82 void getdeep(int u, int fa)
     83 {
     84     if (deep[u] <= k)
     85     {
     86         int tmp = dist[u] + t[k - deep[u] + 1].first;
     87         if (tmp == res[0]) res[1] += t[k - deep[u] + 1].second;
     88         else if (tmp > res[0]) res[0] = tmp, res[1] = 1;
     89     }
     90     erp(G[1], u) if (v != fa && !vis[v])
     91     {
     92         deep[v] = deep[u] + 1;
     93         dist[v] = dist[u] + w;
     94         getdeep(v, u);
     95     }
     96 }
     97 
     98 void add(int u, int fa, int flag)
     99 {
    100     if (deep[u] <= k)
    101     {
    102         if (flag)
    103         {
    104             if (dist[u] == t[deep[u]].first) ++t[deep[u]].second;
    105             else if (dist[u] > t[deep[u]].first) t[deep[u]] = pii(dist[u], 1);
    106         }
    107         else t[deep[u]] = pii(0, 0);
    108     }
    109     erp(G[1], u) if (v != fa && !vis[v])
    110         add(v, u, flag);
    111 }
    112 
    113 void solve(int u) 
    114 {
    115     vis[u] = 1;
    116     t[1] = pii(0, 1);
    117     erp(G[1], u) if (!vis[v]) 
    118     {
    119         deep[v] = 2, dist[v] = w;   
    120         getdeep(v, u); add(v, u, 1);  
    121     }
    122     erp(G[1], u) if (!vis[v])
    123         add(v, u, 0);  
    124     erp(G[1], u) if (!vis[v])
    125     {
    126         sum = f[0] = sze[v]; root = 0;
    127         getroot(v, 0);
    128         solve(root);
    129     }
    130 }
    131 
    132 void Run()
    133 {
    134     while (scanf("%d%d%d", &n, &m, &k) != EOF) 
    135     {
    136         G[0].init(); G[1].init();
    137         memset(res, 0, sizeof res);
    138         memset(vis, 0, sizeof vis);
    139         for (int i = 1, u, v, w; i <= m; ++i)
    140         {
    141             scanf("%d%d%d", &u, &v, &w);
    142             G[0].add(u, v, w);
    143         }
    144         Dijkstra();
    145         sum = f[0] = n; root = 0;
    146         getroot(1, 0); 
    147         solve(root);
    148         printf("%d %d
    ", res[0], res[1]); 
    149     }
    150 }
    151 
    152 int main()
    153 {
    154     #ifdef LOCAL
    155         freopen("Test.in", "r", stdin);
    156     #endif 
    157 
    158     Run();
    159     return 0;
    160 }
    View Code
  • 相关阅读:
    canvas 学习
    configure/autoconf/automake文件相关
    git add A 和 git add . 的区别详解
    Vim格Vim格式化代码功能——gg=G式化代码功能——gg=G
    详解git commit amend 用法
    git reset HEAD 与 git reset hard HEAD的区别 天地逍遥
    git的撤销操作:reset、checkout和revert
    参与linux社区
    git制作补丁
    git diff、git diff head、git diff cached三者详细区分
  • 原文地址:https://www.cnblogs.com/Dup4/p/10284567.html
Copyright © 2020-2023  润新知