zoukankan      html  css  js  c++  java
  • b_lg_按位奶牛(预处理点权和边权)

    john走访完所有的奶牛之后,还要回到他的出发地。
    每次路过牧场i的时候,john必须花Ci的时间和奶牛交谈,即使之前已经做过工作
    请你计算一下,约翰要拆除哪些道路,才能让谈话(忽悠)奶牛的时间变得最少?

    知道是MST,但回程难以模拟,故直接将边权设为:边权*2+两个端点的点权
    注:由于和起点相连的边一开始就被加到一个连通块中,假如起点出度为2,则起点需要被经过3次才对,但kruskal只会算两次,故还要加上最小的点权(起点的点权)

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+5, M=1e6+5;
    int n,m,fa[N],c[N];
    struct edge {
        int u,v,w;
    }e[M];
    int find(int u) {return fa[u]==u ? u : fa[u]=find(fa[u]);}
    int kruskal() {
        for (int i=1; i<=n; i++) fa[i]=i;
        sort(e,e+m,[&](edge a, edge b){return a.w<b.w;});
        int ans=0;
        for (int i=0; i<m; i++) {
            int fu=find(e[i].u), fv=find(e[i].v);
            if (fu!=fv) {
                fa[fu]=fv;
                ans+=e[i].w;
            }
        }
        return ans;
    }
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        cin>>n>>m;
        for (int i=1; i<=n; i++) cin>>c[i];
        for (int i=0; i<m; i++) cin>>e[i].u>>e[i].v>>e[i].w, e[i].w=2*e[i].w+c[e[i].u]+c[e[i].v];
        cout<<*min_element(c+1,c+n+1)+kruskal();
        return 0;
    }
    

    我的疑惑:kruskal不是按照边权+点权排序的吗?那约束有两个啊,万一和点权很小的点连接的边权很大(那就不是起点了啊),那这个额外加不就错了吗

  • 相关阅读:
    C#日期加减
    c#的预编译指令
    IHttpModule与IHttpHandler的区别整理
    ASP.NET提供程序
    在所有页面共享通用行为
    5.Oracle中的数据表
    asp.net跳转页面的三种方法比较(转)
    C#实现经典排序算法
    ASP.NET用户登录模块代码
    http错误锦集
  • 原文地址:https://www.cnblogs.com/wdt1/p/13815653.html
Copyright © 2011-2022 走看看