Codeforces Round #597 (Div. 2)
题意:n个城市,每个城市要么自己建发电站(花费Ci),要么和建有发电站的城市相连(花费Ki+Kj),问所有城市通电的最小花费,并输出方案

比赛的时候根本没写到这里,昨晚真的。。。毒瘤场,队友对着A过的代码改了半小时,我快读板子出锅了Debug好久才D出来。。

题目如果只有第二种建造方法,不就是最小生成树板子吗???(设定一个建造发电厂)
再仔细一想,第一种情况的建造我们也可以把他改成两个点之间的联系:
设定一个源点0,并将源点的Ki值设定为0,那么第一种情况就是i点与0点建边了!
#include <bits/stdc++.h>
using namespace std;
#define endll '\n'
#define C getchar()
using ll = long long;
#define pi acos(-1.0)
#define INF 0x3f3f3f3f
#define mod 1000000007
#define pii pair<int, int>
const int MAXN = 1e6 + 10;
#define stop system("pause")
#define lowbit(x) ((x) & (-x))
#define Temp template <typename T>
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, b) for (int i = a; i <= b; ++i)

Temp inline void rd(T &s)
{
    s = 0;T t = 1, k = C;
    for (; k < '0' || k > '9'; k = C)if (k == '-') t = -1;
    for (; k >= '0' && k <= '9'; k = C) s = (s << 1) + (s << 3) + (k ^ 48);
    s *= t;
}
const int N = 2005;
int x[N], y[N], k[N],c[N],par[N];
ll cost[N][N],dist[N];
bool done[N];
int main()
{
    int n;rd(n);
    rep(i,1,n) rd(x[i]),rd(y[i]);
    rep(i,1,n) rd(c[i]);
    rep(i,1,n) rd(k[i]);
    rep(i,1,n) rep(j,1,n)  cost[i][j] = 1LL * (k[i] + k[j]) * (abs(x[i] - x[j]) + abs(y[i] - y[j]));
    for (int i = 1; i <= n; i++)  cost[0][i] = c[i];//秒啊%%%
    for (int i = 1; i <= n; i++) dist[i] = 1e18;
    vector<int> ps;
    vector<pii > edges;
    mem(par, -1);
    ll ans = 0;
    rep(i,0,n)
    {
        ll mn = 1e18, id = -1;
        rep(i,0,n)
            if (!done[i] && dist[i] < mn)
                mn = dist[i],id = i;
        done[id] = 1;
        ans += dist[id];
        if (par[id] == 0)
            ps.push_back(id);
        else if (par[id] > 0)
            edges.push_back({par[id], id});
        rep(i,0,n)
            if (dist[i] > cost[id][i])
                dist[i] = cost[id][i],par[i] = id;
    }
    cout << ans << endl<< ps.size() << endl;
    for (int x : ps) cout << x << " ";
    cout << endl<< edges.size() << endl;
    for (auto pr : edges)  cout << pr.first << " " << pr.second << "\n";
}