zoukankan      html  css  js  c++  java
  • Imperial roads 非严格次小生成树

    cf测评姬比uva快了五倍。。。

    /*
    不管这条边是不是在mst上,直接跑lca求出路径上的最大边w即可
    ans=mst-w+dist(u,v) 
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 100007
    struct Edge{int to,nxt,w;}edge[maxn<<1];
    struct E{int u,v,w,flag;}e[maxn<<1];
    int cmp(E a,E b){return a.w<b.w;}
    int head[maxn],tot,n,m,q; 
    map<int,int>mp[maxn];
    /*4 5 2 1 3*/
    void addedge(int u,int v,int w){
        edge[tot].w=w;
        edge[tot].to=v;
        edge[tot].nxt=head[u];
        head[u]=tot++;
    }
    int F[maxn];
    int find(int x){
        return F[x]==-1?x:F[x]=find(F[x]);
    }
    int kruskal(){
        memset(F,-1,sizeof F);
        sort(e+1,e+1+m,cmp);
        int cnt=0,res=0;
        for(int i=1;i<=m;i++){
            int f1=find(e[i].u),f2=find(e[i].v);
            if(f1==f2)continue;
            addedge(e[i].u,e[i].v,e[i].w);
            addedge(e[i].v,e[i].u,e[i].w);
            res+=e[i].w;
            F[f1]=f2;
            if(++cnt==n)break;
        }
        return res;
    }
    
    int d[maxn],f[maxn][30],dp[maxn][30];
    void bfs(){
        memset(d,0,sizeof d);
        memset(f,0,sizeof f);
        memset(dp,0,sizeof dp);
        queue<int>q;
        q.push(1);
        d[1]=1;
        while(!q.empty()){
            int x=q.front();q.pop();
            for(int i=head[x];i!=-1;i=edge[i].nxt){
                int y=edge[i].to;
                if(d[y])continue;
                d[y]=d[x]+1;
                f[y][0]=x;
                dp[y][0]=edge[i].w;
                for(int k=1;k<=20;k++){
                    f[y][k]=f[f[y][k-1]][k-1];
                    dp[y][k]=max(dp[y][k-1],dp[f[y][k-1]][k-1]);
                }
                q.push(y);
            }
        }
    }
    int lca(int x,int y){//返回路径上的最大边 
        int res=0;
        if(d[x]<d[y])swap(x,y);
        for(int i=20;i>=0;i--)    
            if(d[f[x][i]]>=d[y]){
                res=max(res,dp[x][i]);
                x=f[x][i];
            }
        if(x==y)return res;
        for(int i=20;i>=0;i--)
            if(f[x][i]!=f[y][i]){
                res=max(res,max(dp[x][i],dp[y][i]));
                x=f[x][i],y=f[y][i];
            }
        res=max(res,max(dp[x][0],dp[y][0]));
        return res;
    }
    
    void init(){
        memset(head,-1,sizeof head);
        memset(e,0,sizeof e);
        memset(edge,0,sizeof edge);
        for(int i=1;i<=n;i++)mp[i].clear();
        tot=0;
    }
    int main(){
        while(scanf("%d%d",&n,&m)==2){
            init();
            for(int i=1;i<=m;i++){
                scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
                mp[e[i].u][e[i].v]=mp[e[i].v][e[i].u]=e[i].w;
            }
            int mst=kruskal();
            bfs();
            scanf("%d",&q);
            while(q--){
                int u,v;
                scanf("%d%d",&u,&v);
                
                cout<<mst-lca(u,v)+mp[u][v]<<endl;
            }
        }    
    }
  • 相关阅读:
    VMware 虚拟机下载与安装
    技术点
    使用 localstorage 写入浏览器并获取
    Vue 生命周期
    Java程序中使用 Jsoup 爬虫( 简单示例 )
    Java程序中实现 MySQL数据库的备份与还原
    微信小程序快捷键(Mac和windows)
    SEO需要掌握的基础知识
    好用的图片压缩在线网站(几乎不损伤图片质量)
    CSS3新增伪类--好用的:target
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10516229.html
Copyright © 2011-2022 走看看