zoukankan      html  css  js  c++  java
  • Minimum spanning tree for each edge(倍增LCA)

    https://vjudge.net/contest/320992#problem/J

    暑期训练的题。

    题意:给你一个n个点,m条边的无向图。对于每一条边,求包括该边的最小生成树。

    思路:首先想到求一次整图的mst后,对每条边(u,v),如果该边在整图的最小生成树上,答案就是mst,否则,加入的边(u,v)会使原来的最小生成树成环,可以通过lca确定该环,那么只要求出u到lca(u,v)路径上的最大边权和v到lca(u,v)路径上的最大边权中的最大值mx,mst-mx+w[u.v]就是答案。其中gx[u][i]表示节点u到其第2^i个祖先路径上的最大边权。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int INF = 0x3f3f3f3f;
      4 const int N = 2e5 + 10;
      5 const int DEG = 20;
      6 typedef long long ll;
      7 struct edge {
      8     int v, w, next;
      9     edge() {}
     10     edge(int v, int w, int next) : v(v), w(w), next(next){}
     11 }e[N << 1];
     12 
     13 int head[N], tot;
     14 int fa[N][DEG], deg[N];
     15 int gx[N][DEG];
     16 void init() {
     17     memset(head, -1, sizeof head);
     18     tot = 0;
     19 }
     20 void addedge(int u, int v, int w) {
     21     e[tot] = edge(v, w, head[u]);
     22     head[u] = tot++;
     23 }
     24 void BFS(int root) {
     25     queue<int> que;
     26     deg[root] = 0;
     27     fa[root][0] = root;
     28     gx[root][0] = 0;
     29     que.push(root);
     30     while(!que.empty()) {
     31         int tmp = que.front();
     32         que.pop();
     33         for(int i = 1; i < DEG; ++i) {
     34             fa[tmp][i] = fa[ fa[tmp][i - 1] ][i - 1];
     35             gx[tmp][i] = max(gx[tmp][i - 1], gx[ fa[tmp][i - 1] ][i - 1]);
     36           // printf("[%d %d] ", tmp, gx[tmp][i]);
     37         }
     38        // puts("");
     39         for(int i = head[tmp]; ~i; i = e[i].next) {
     40             int v = e[i].v;
     41             int w = e[i].w;
     42             if(v == fa[tmp][0]) continue;
     43             deg[v] = deg[tmp] + 1;
     44             fa[v][0] = tmp;
     45             gx[v][0] = w;
     46             que.push(v);
     47         }
     48     }
     49 }
     50 int Mu, Mv;
     51 ll LCA(int u, int v) {
     52     Mu = Mv = -1;
     53     if(deg[u] > deg[v]) swap(u, v);
     54     int hu = deg[u], hv = deg[v];
     55     int tu = u, tv = v;
     56     for(int det = hv - hu, i = 0; det; det >>= 1, ++i)
     57         if(det & 1) { Mv = max(Mv, gx[tv][i]); tv = fa[tv][i];  }
     58     if(tu == tv) return Mv;
     59     for(int i = DEG - 1; i >= 0; --i) {
     60         if(fa[tu][i] == fa[tv][i]) continue;
     61         Mu = max(Mu, gx[tu][i]);
     62         Mv = max(Mv, gx[tv][i]);
     63         tu = fa[tu][i];
     64         tv = fa[tv][i];
     65 
     66 
     67     }
     68     return max(max(Mu, gx[tu][0]), max(Mv, gx[tv][0]));
     69 }
     70 
     71 int U[N], V[N], w[N], r[N], f[N];
     72 int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }
     73 bool cmp(int a, int b) { return w[a] < w[b]; }
     74 ll MST;
     75 int n, m;
     76 void mst() {
     77 
     78     scanf("%d%d", &n, &m);
     79     for(int i = 1; i <= m; ++i) {
     80         scanf("%d%d%d", &U[i], &V[i], &w[i]);
     81         r[i] = i;
     82         f[i] = i;
     83     }
     84     sort(r + 1, r + m + 1, cmp);
     85     MST = 0;
     86     for(int i = 1; i <= m; ++i)
     87     {
     88         int id = r[i];
     89         int fu = find(U[id]);
     90         int fv = find(V[id]);
     91         if(fu != fv) {
     92             MST += w[id];
     93             f[ fu ] = fv;
     94             addedge(U[id], V[id], w[id]);
     95             addedge(V[id], U[id], w[id]);
     96         }
     97     }
     98 }
     99 int main() {
    100     init();
    101     mst();
    102     BFS(1);
    103 
    104     for(int i = 1; i <= m; ++i) {
    105         printf("%I64d
    ", MST - LCA(U[i], V[i]) + w[i]);
    106     }
    107     return 0;
    108 }
    View Code
  • 相关阅读:
    django中有外键关系两张表的相互查找方法
    Python的Django框架中forms表单类的使用方法详解
    Django 模板中 变量 过滤器 标签 的使用方法
    Django如何让未登录的用户自动跳转至登录页
    Django 前后台的数据传递
    用css实现在横线中间插入文字
    CSS控制字体在一行内显示不换行
    如何在python3环境下的Django中使用MySQL数据库
    Linux小技巧之:两种方法统计访问web网站的前10个IP
    通过explain分析低效的SQL执行计划
  • 原文地址:https://www.cnblogs.com/wzgg/p/11386438.html
Copyright © 2011-2022 走看看