• Codeforces Round #597 (Div. 2) D. Shichikuji and Power Grid


    链接:

    https://codeforces.com/contest/1245/problem/D

    题意:

    Shichikuji is the new resident deity of the South Black Snail Temple. Her first job is as follows:

    There are n new cities located in Prefecture X. Cities are numbered from 1 to n. City i is located xi km North of the shrine and yi km East of the shrine. It is possible that (xi,yi)=(xj,yj) even when i≠j.

    Shichikuji must provide electricity to each city either by building a power station in that city, or by making a connection between that city and another one that already has electricity. So the City has electricity if it has a power station in it or it is connected to a City which has electricity by a direct connection or via a chain of connections.

    Building a power station in City i will cost ci yen;
    Making a connection between City i and City j will cost ki+kj yen per km of wire used for the connection. However, wires can only go the cardinal directions (North, South, East, West). Wires can cross each other. Each wire must have both of its endpoints in some cities. If City i and City j are connected by a wire, the wire will go through any shortest path from City i to City j. Thus, the length of the wire if City i and City j are connected is |xi−xj|+|yi−yj| km.
    Shichikuji wants to do this job spending as little money as possible, since according to her, there isn't really anything else in the world other than money. However, she died when she was only in fifth grade so she is not smart enough for this. And thus, the new resident deity asks for your help.

    And so, you have to provide Shichikuji with the following information: minimum amount of yen needed to provide electricity to all cities, the cities in which power stations will be built, and the connections to be made.

    If there are multiple ways to choose the cities and the connections to obtain the construction of minimum price, then print any of them.

    思路:

    最小生成树,将每个点和n+1连边为建电站,然后跑最小生成树即可。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
     
    const int MAXN = 2e3+10;
    struct Edge
    {
        int u, v;
        LL w;
        bool operator < (const Edge& rhs) const
        {
            return this->w < rhs.w;
        }
    }edge[MAXN*MAXN+MAXN];
     
    int n;
    int c[MAXN], k[MAXN];
    int x[MAXN], y[MAXN];
    int Fa[MAXN];
     
    int GetFa(int x)
    {
        if (Fa[x] == x)
            return x;
        Fa[x] = GetFa(Fa[x]);
        return Fa[x];
    }
     
    int main()
    {
        scanf("%d", &n);
        for (int i = 1;i <= n+1;i++)
            Fa[i] = i;
        for (int i = 1;i <= n;i++)
            scanf("%d%d", &x[i], &y[i]);
        for (int i = 1;i <= n;i++)
            scanf("%d", &c[i]);
        for (int i = 1;i <= n;i++)
            scanf("%d", &k[i]);
        int tot = 0;
        for (int i = 1;i <= n;i++)
        {
            for (int j = i+1;j <= n;j++)
            {
                LL len = abs(x[i]-x[j])+abs(y[i]-y[j]);
                edge[++tot].u = i;
                edge[tot].v = j;
                edge[tot].w = len*(k[i]+k[j]);
            }
        }
        for (int i = 1;i <= n;i++)
        {
            edge[++tot].u = n+1;
            edge[tot].v = i;
            edge[tot].w = c[i];
        }
        sort(edge+1, edge+1+tot);
        vector<pair<int, int> > Edg;
        vector<int> Pow;
        LL sum = 0;
        for (int i = 1;i <= tot;i++)
        {
            int tu = GetFa(edge[i].u);
            int tv = GetFa(edge[i].v);
            if (tu == tv)
                continue;
            sum += edge[i].w;
            Fa[tu] = tv;
            if (edge[i].u == n+1)
                Pow.push_back(edge[i].v);
            else
                Edg.emplace_back(edge[i].u, edge[i].v);
        }
        printf("%I64d
    ", sum);
        printf("%d
    ", (int)Pow.size());
        for (auto v: Pow)
            printf("%d ", v);
        puts("");
        printf("%d
    ", Edg.size());
        for (auto p: Edg)
            printf("%d %d
    ", p.first, p.second);
        
        return 0;
    }
    
  • 相关阅读:
    《相约星期二》--[美]米奇·阿尔博姆
    《把信送给加西亚》--[美]阿尔伯特·哈伯德
    《少有人走的路:心智成熟的旅程》--[美]M·斯科特·派克
    《穷爸爸和富爸爸》--[美]罗伯特·清崎,[美]莱希
    Error This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. T
    C#轻量级高性能日志组件EasyLogger
    我们为何要跳槽
    Grid++Report报表工具C/S实战篇(五)
    .NET 开源Protobuf-net从入门到精通
    怎样防止ddos攻击
  • 原文地址:https://www.cnblogs.com/YDDDD/p/11797735.html
Copyright © 2020-2023  润新知