/************************************************************** Problem: 2324 User: gaotianyu1350 Language: C++ Result: Accepted Time:392 ms Memory:7620 kb ****************************************************************/ #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <queue> #include <iostream> using namespace std; #define MAXN 350 #define MAXM 300000 #define INF 0x3f3f3f3f int point[MAXN], next[MAXM], v[MAXM], flow[MAXM], cap[MAXM], w[MAXM]; int lastedge[MAXN], dis[MAXN]; bool check[MAXN]; int tot = -1; int n, m, people; int map[MAXN][MAXN]; inline void init() { memset(map, 0x7f, sizeof(map)); memset(point, -1, sizeof(point)); memset(next, -1, sizeof(next)); tot = -1; } inline void addedge(int x, int y, int theCap, int theDis) { tot++; next[tot] = point[x]; point[x] = tot; v[tot] = y; flow[tot] = 0; cap[tot] = theCap; w[tot] = theDis; tot++; next[tot] = point[y]; point[y] = tot; v[tot] = x; flow[tot] = 0; cap[tot] = 0; w[tot] = - theDis; } inline int addflow(int s, int t) { int now = t; int ans = INF; while (now != s) { int temp = lastedge[now]; ans = min(ans, cap[temp] - flow[temp]); now = v[lastedge[now] ^ 1]; } now = t; while (now != s) { flow[lastedge[now]] += ans; flow[lastedge[now] ^ 1] -= ans; now = v[lastedge[now] ^ 1]; } return ans; } bool spfa(int s, int t, int &maxflow, int &mincost) { queue<int> q; while (!q.empty()) q.pop(); memset(dis, 0x7f, sizeof(dis)); memset(check, 0, sizeof(check)); dis[s] = 0; check[s] = true; q.push(s); while (!q.empty()) { int now = q.front(); q.pop(); check[now] = false; for (int temp = point[now]; temp != -1; temp = next[temp]) if (flow[temp] < cap[temp] && dis[now] + w[temp] < dis[v[temp]]) { dis[v[temp]] = dis[now] + w[temp]; lastedge[v[temp]] = temp; if (!check[v[temp]]) check[v[temp]] = true, q.push(v[temp]); } } if (dis[t] > INF) return false; int add = addflow(s, t); maxflow += add; mincost += add * dis[t]; return true; } inline int solve(int s, int t) { int maxflow = 0, mincost = 0; while (spfa(s, t, maxflow, mincost)); /*{ int tiaoshi = 1; tiaoshi++; }*/ //printf("mflow :%d\n", maxflow); return mincost; } inline void build(int start, int end) { addedge(start, 0, people, 0); for (int i = 1; i <= n; i++) { addedge(i, end, 1, 0); addedge(start, i + n, 1, 0); //addedge(i, i + n, INF, 0); } for (int k = 0; k <= n; k++) for (int i = 0; i <= n; i++) for (int j = 0; j <= n; j++) if (i != j) { if (map[i][k] < INF && map[k][j] < INF) map[i][j] = min(map[i][j], map[i][k] + map[k][j]); if (k == j && i < j && map[i][j] < INF) addedge(i == 0 ? 0 : i + n, j, INF, map[i][j]); } } int main() { //freopen("input.txt", "r", stdin); init(); scanf("%d%d%d", &n, &m, &people); for (int i = 1; i <= m; i++) { int x, y, z; scanf("%d%d%d", &x, &y, &z); if (z < map[x][y]) map[x][y] = map[y][x] = z; } build(2 * n + 1, 2 * n + 2); printf("%d\n", solve(2 * n + 1, 2 * n + 2)); }
[BZOJ2324][ZJOI2011][最小费用最大流]营救皮卡丘,布布扣,bubuko.com
[BZOJ2324][ZJOI2011][最小费用最大流]营救皮卡丘
原文地址:http://www.cnblogs.com/mengfanrong/p/3845444.html