#10 RE求助
查看原帖
#10 RE求助
76495
chichow楼主2020/10/9 21:58

如题,谢谢了!

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <queue>
#define EL puts("")
#define MAXN 100000
#define MAXM 300000
#define LOG2N 18
//#define FOPEN 1
//#define DEBUG 1
using namespace std;
int n,m,p_edge[MAXM+100],fa[MAXN+100],dep[MAXN+100],firmax,secmax,maxdepth=-1;
int f1[MAXN+10][LOG2N+1],f2[MAXN+10][LOG2N+1],f3[MAXN+10][LOG2N+1];
long long micnt=0,secnt;
bool e_used[MAXM+100];
vector<int> g[MAXN+100];
struct EdgeNode{
    int from, to ,w;
}edge[MAXM+100];
struct GlobalVar{
    int re1,re2;
}gv;
bool cmp(int p1,int p2){
    return edge[p1].w < edge[p2].w;
}
int getFa(int x){
    if (x == fa[x]) return x;
    return fa[x] = getFa(fa[x]);
}
void kruskal(){
    int cnt = 0;
    for (int i=1; i<=m; i++){
        int pe = p_edge[i];
        int faa = getFa(edge[pe].from),
            fab = getFa(edge[pe].to);
        if (faa != fab){
            micnt += edge[pe].w;
            e_used[pe] = true;
            cnt ++;
            fa[faa] = fab;
        }
        if (cnt==n-1) break;
    }
}
void dfs(int x, int fa, int wei, int d){
    f1[x][0] = fa;
    f2[x][0] = wei;
    f3[x][0] = wei;
    dep[x] = d;
    int sz = g[x].size();
    for (int i=0; i<sz; i++){
        int pe = g[x][i];
        if (!e_used[pe]) continue;
        int son = edge[pe].from;
        if (son == x) son = edge[pe].to;
        if (son == fa) continue;
        dfs(son, x, edge[pe].w, d+1);
    }
}
void lca(int a,int b){
    if (dep[a] < dep[b]) swap(a,b);
    priority_queue<int> q;
    for (int i=log2(dep[a]-dep[b]); i>=0; i--){
        if ((1<<i) <= dep[a]-dep[b]){
            q.push(f2[a][i]);
            q.push(f3[a][i]);
            a = f1[a][i];
        }
    }
    if (a==b) goto RE;
    for (int i=log2(dep[a]); i>=0; i--){
        if (f1[a][i] != f1[b][i]){
            q.push(f2[a][i]);
            q.push(f3[a][i]);
            q.push(f2[b][i]);
            q.push(f3[b][i]);
            a = f1[a][i];
            b = f1[b][i];
        }
    }
    q.push(f2[a][0]);
    q.push(f3[a][0]);
    q.push(f2[b][0]);
    q.push(f3[b][0]);
    RE:
    gv.re1 = q.top();q.pop();
    while (!q.empty()){
        gv.re2 = q.top();q.pop();
        if (gv.re1 != gv.re2) return;
    }
}
int main(){
#ifdef FOPEN
    freopen("input","r",stdin);
#endif
    int x,y,z;
    cin>>n>>m;
    for (int i=1; i<=m; i++){
        scanf("%d%d%d",&x,&y,&z);
        g[x].push_back(i);
        g[y].push_back(i);
        edge[i].from = x;
        edge[i].to   = y;
        edge[i].w    = z;
        p_edge[i] = i;
    }
    sort(p_edge+1,p_edge+1+m,cmp);
    memset(e_used, false, sizeof(e_used));
    for (int i=1; i<=n; i++) fa[i] = i;
    kruskal();
    dfs(1, 1, -1, 0);
#ifdef DEBUG
    printf("mincnt = %lld\n", micnt);
#endif
    for (int i=1; i<=LOG2N; i++){
        for (int u=1; u<=n; u++){
            priority_queue<int> q;
            f1[u][i] = f1[ f1[u][i-1] ][i-1];
            q.push(f2[u][i-1]);
            q.push(f3[u][i-1]);
            q.push(f2[ f1[u][i-1] ][i-1]);
            q.push(f3[ f1[u][i-1] ][i-1]);
            f2[u][i] = q.top();q.pop();
            while (!q.empty()){
                f3[u][i] = q.top();q.pop();
                if (f3[u][i] != f2[u][i]) break;
            }
        }
    }
    int minn = 1000000000;
    for (int i=1; i<=m; i++){
        if (!e_used[i]){
            lca(edge[i].from, edge[i].to);
#ifdef DEBUG
            printf("from = %d, to = %d, gv.re1 = %d, gv.re2 = %d\n",edge[i].from, edge[i].to,gv.re1,gv.re2);
#endif
            int t;
            if (gv.re1 == edge[i].w) t = gv.re2;
            else t = gv.re1;
            if (t == edge[i].w) continue;
            if (t == edge[i].w-1){
                printf("%lld",micnt+1);
                return 0;
            }
            if (edge[i].w - t < minn) minn = edge[i].w -t;
        }
    }
    printf("%lld",micnt + minn);
#ifdef FOPEN
    fclose(stdin);
#endif
}
2020/10/9 21:58
加载中...