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

Meaning of the questions: There are n cities, you can build power stations in the city, or to other cities have electricity, so that all cities have electricity. It allows you to calculate the minimum cost to complete this project.

 

Ideas: about abstract issues, found difficulty is that we do not know what changed build power stations in several cities, this time we should use the " super-source " technique of (big brother saw the solution to a problem I know of ... ).

   We fictional one point X, and X and all cities have the connection path, the path length is the construction cost of the power station.

   In this way, the problem is transformed into a minimum spanning tree.

   

//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#pragma GCC optimize(2)
#include <bits/stdc++.h>

using namespace std;
typedef double dou;
typedef long long ll;
typedef pair<int, int> pii;
typedef map<int, int> mii;

#define pai acos(-1.0)
#define M 1000500
#define inf 0x3f3f3f3f
#define mod 1000000007
#define IN inline
#define W(a) while(a)
#define lowbit(a) a&(-a)
#define left k<<1
#define right k<<1|1
#define lson L, mid, left
#define rson mid + 1, R, right
#define ms(a,b) memset(a,b,sizeof(a))
#define Abs(a) (a ^ (a >> 31)) - (a >> 31)
#define random(a,b) (rand()%(b+1-a)+a)
#define false_stdio ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)

ll n;
ll cnt;
ll boss[2005], x[2005], y[2005], k[2005];
struct Data {
    ll u, v, w;
}edge[M<<2];
set<int>built;
vector<pii>load;

int find(int t) {
    if (boss[t] == t)return t;
    return boss[t] = find(boss[t]);
}

int main () {
    false_stdio;
    cin >> n;
    for (int i = 0; i <= n; i++)boss[i] = i;
    for (int i = 1; i <= n; i++)cin >> x[i] >> y[i];
    for (int i = 1,c; i <= n; i++) {
        cin >> c;
        edge[++cnt] = Data{ 0,i,c };
    }
    for (int i = 1; i <= n; i++)cin >> k[i];

    for (int i = 1; i < n; i++) {
        for (int j = i + 1; j <= n; j++) {
            ++cnt;
            edge[cnt].u = i;
            edge[cnt].v = j;
            edge[cnt].w = (abs(x[i] - x[j]) + abs(y[i] - y[j])) * (k[i] + k[j]);
        }
    }
    sort(edge + 1, edge + cnt + 1, [](Data& a, Data& b) {return a.w < b.w; });

    ll ans = 0;
    for (int i = 1; i <= cnt; i++) {
        if (edge[i].w < 0)break;
        int u = edge[i].u;
        int v = edge[i].v;
        int w = edge[i].w;
        int fu = find(u), fv = find(v);
        if (fu == fv)continue;
        boss[fu] = fv;
        ans += w;
        if (u == 0)built.insert(v);
        else load.push_back(pii(u, v));
    }

    cout << ans << endl;

    cout << built.size() << endl;
    for (auto iter : built)cout << iter << ' ';
    cout << endl;

    cout << load.size() << endl;
    for (auto iter : load) {
        cout << iter.first << ' ' << iter.second << endl;
    }
    
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/caibingxu/p/11783939.html