zoukankan      html  css  js  c++  java
  • CF1245D: Shichikuji and Power Grid

    CF1245D: Shichikuji and Power Grid

    题意描述:

    • 给定(n)个点((nleq2000)),在第(i)个点上建立一个基站需要(c_i)的代价,连接两个点需要((|x_i-x_j|+|y_i-y_j|)*(k_i+k_j))的代价。对于一个点要么建立基站,要么连接建立基站的点。问最小代价是多少,同时输出建立基站的点和线路。

    思路:

    • 建立一个超级根,对于每个城市建立发电站,连接一条权值为(c_i)的边,再把每个城市之间连接电线的花费算出来,跑(kruskal)
    • 在跑的过程中记录哪些城市建立了发电站,哪些城市建立了电线。
    • (hint:)注意开(long long)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 2000 + 10;
    int n;
    ll ans, x[maxn], y[maxn], k[maxn], c[maxn];
    struct Node{
        int x, y;
        ll z;
    }p[maxn*maxn];
    
    int tot;
    void add_edge(int x, int y, ll z){
        p[++tot].x = x, p[tot].y = y, p[tot].z = z;
    }
    
    int fa[maxn];
    
    bool cmp(Node a, Node b){
        return a.z < b.z;
    }
    
    int get_fa(int x)
    {
        if(x == fa[x]) return x;
        return fa[x] = get_fa(fa[x]);
    }
    
    int ans1[maxn], cnt1;
    int ax[maxn], ay[maxn], cnt2;
    
    void kruskal()
    {
        for(int i = 0; i <= n; i++) fa[i] = i;
        sort(p+1, p+1+tot, cmp);
        int cnt = 0;
        for(int i = 1; i <= tot; i++)
        {
            int x = p[i].x, y = p[i].y;
            ll z = p[i].z;
            int fx = get_fa(x), fy = get_fa(y);
            if(fx != fy)
            {
                if(x == 0 || y == 0) ans1[++cnt1] = x + y;
                else ax[++cnt2] = x, ay[cnt2] = y;
                ans += z; fa[fx] = fy; cnt++;
            }
            if(cnt == n) break;
        }
        cout << ans << endl;
    }
    
    int main()
    {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++)
            scanf("%lld%lld", &x[i], &y[i]);
        for(int i = 1; i <= n; i++) scanf("%lld", &c[i]);
        for(int i = 1; i <= n; i++) scanf("%lld", &k[i]);
    
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
        {
            if(i != j)
            {
                ll w = (k[i] + k[j]) * (abs(x[i]-x[j]) + abs(y[i]-y[j]));
                add_edge(i, j, w);
            }
        }
    
        for(int i = 1; i <= n; i++)
            add_edge(0, i, c[i]), add_edge(i, 0, c[i]);
    
        kruskal();
        cout << cnt1 << endl;
        for(int i = 1; i <= cnt1; i++)
            printf("%d ", ans1[i]); puts("");
        cout << cnt2 << endl;
        for(int i = 1; i <= cnt2; i++)
            printf("%d %d
    ", ax[i], ay[i]);
        return 0;
    }
    
  • 相关阅读:
    redis liunx安装
    db2实现每条数据累加
    js实现目录链接,内容跟着目录滚动显示
    Anaconda3安装过程中遇到“Anaconda3-5.1.0-Linux-x86_64.sh:行350: bunzip2: 未找到命令 tar: 它似乎不像是一个 tar 归档文件 tar: 由于前次错误,将以上次的错误状态退出”
    java axis2生成wsdl
    java axis2解析xml(wsdl返回List数据Map<String,Object>
    java axis2解析xml(wsdl返回List数据Map<String,String>
    java axis2解析xml(wsdl返回List数据)
    jquery 合并单元格,rowspan
    poi导出excel
  • 原文地址:https://www.cnblogs.com/zxytxdy/p/11781292.html
Copyright © 2011-2022 走看看