【BZOJ2324】[ZJOI2011]营救皮卡丘 给定起点最小权K链覆盖

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef int JQK;
namespace MCMF {
        const JQK INF = 0x7f7f7f7f;
        const int MAXN = 505, MAXM = 130000;
        int Head[MAXN], cur[MAXN], to[MAXM << 1], nxt[MAXM << 1], f[MAXM << 1], ed = 1;
        int S, T, MAXP, MAXF, pre[MAXN];
        JQK lev[MAXN], cost[MAXM << 1];
        bool exist[MAXN];
        void addedge(int u, int v, int cap, JQK val) {
                to[++ed] = v;
                nxt[ed] = Head[u];
                Head[u] = ed;
                f[ed] = cap;
                cost[ed] = val;
                to[++ed] = u;
                nxt[ed] = Head[v];
                Head[v] = ed;
                f[ed] = 0;
                cost[ed] = -1 * val;
                return;
        }
        bool spfa() {
                int u;
                queue<int>q;
                for (int i = 0; i <= MAXP + 1; i++) {
                        exist[i] = 0;
                        lev[i] = INF;
                }
                //memset(exist, false, sizeof(exist));
                //memset(lev, 127, sizeof(lev));
                lev[S] = pre[S] = 0;
                q.push(S);
                while (q.size()) {
                        u = q.front();
                        q.pop();
                        exist[u] = false;
                        for (int i = Head[u]; i; i = nxt[i])
                                if (f[i] && lev[u] + cost[i] < lev[to[i]]) {
                                        lev[to[i]] = lev[u] + cost[i];
                                        pre[to[i]] = i;
                                        if (!exist[to[i]]) {
                                                exist[to[i]] = true;
                                                q.push(to[i]);
                                        }
                                }
                }
                for (int i = 0; i <= MAXP + 1; i++) {
                        cur[i] = Head[i];
                }
                //memcpy(cur, Head, sizeof(Head));
                return lev[T] != INF;
        }
        JQK Augment() {
                JQK delta = 0x7f7f7f7f;
                for (int i = pre[T]; i; i = pre[to[i ^ 1]])
                        if (f[i] < delta) {
                                delta = f[i];
                        }
                for (int i = pre[T]; i; i = pre[to[i ^ 1]]) {
                        f[i] -= delta;
                        f[i ^ 1] += delta;
                }
                MAXF += delta;
                return delta * lev[T];
        }
        void init(int S1, int T1) {
                MAXF = 0;
                memset(Head, 0, sizeof(Head));
                ed = 1;
                S = S1;
                T = T1;
                return;
        }
        JQK mcmf() {
                JQK ans = 0;
                memset(exist, false, sizeof(exist));
                while (spfa())
                        //ans+=DFS(S,INF)*lev[T];
                {
                        ans += Augment();
                }
                return ans;
        }
}
int n, m, k, dis[205][205];
int main() {
        int u, v, c;
        scanf("%d %d %d", &n, &m, &k);
        memset(dis, 63, sizeof(dis));
        for (int i = 1; i <= m; i++) {
                scanf("%d %d %d", &u, &v, &c);
                dis[u][v] = dis[v][u] = min(dis[u][v], c);
        }
        for (int k = 0; k <= n; k++) {
                for (int i = 0; i <= n; i++) {
                        for (int j = 0; j <= n; j++) {
                                if (k <= i || k <= j)
                                        dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
                        }
                }
        }
        int s, t;
        s = 2 * (n + 1) + 2, t = s + 1;
        MCMF::MAXP = t + 1;
        MCMF::init(s, t);
        MCMF::addedge(s, 0, k, 0);
        for (int i = 1; i <= n; i++) {
                MCMF::addedge(s, i, 1, 0);
                MCMF::addedge(i + n, t, 1, 0);
        }
        for (int i = 0; i <= n; i++) {
                for (int j = i + 1; j <= n; j++) {
                        MCMF::addedge(i, j + n, 1, dis[i][j]);
                }
        }
        cout << MCMF::mcmf();
        return 0;
}

猜你喜欢

转载自www.cnblogs.com/Aragaki/p/11756493.html