Created
May 30, 2014 15:22
-
-
Save KT-Yeh/4a9b6fe64f5f3ae1f198 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdio> | |
#include <cstring> | |
#include <vector> | |
#include <queue> | |
#include <algorithm> | |
using namespace std; | |
#define INF 999999 | |
using llt = long long int; | |
llt N, M, D, K; | |
vector<int> edge[105]; | |
llt cap[105][105], flow[105][105], cost[105][105]; | |
llt pre[105], dis[105]; | |
void Initial(); | |
llt MCMF(llt S, llt T); | |
bool SPFA(llt S, llt T); | |
llt FindMinFlow(llt S, llt T); | |
void UpdateFlow(llt S, llt T, llt bottleneck); | |
int main() | |
{ | |
while (scanf("%d %d", &N, &M) == 2) { | |
Initial(); | |
llt u, v, c; | |
for (llt i = 0; i < M; ++i) { | |
scanf("%lld %lld %lld", &u, &v, &c); | |
edge[u].push_back(v); | |
edge[v].push_back(u); | |
cost[u][v] = cost[v][u] = c; | |
} | |
scanf("%lld %lld", &D, &K); | |
for (llt i = 1; i <= N; ++i) | |
for (llt j : edge[i]) cap[i][j] = K; | |
edge[0].push_back(1); | |
cap[0][1] = D; | |
llt result = MCMF(0, N); | |
if (result == -1) puts("Impossible."); | |
else printf("%lld\n", result); | |
} | |
} | |
void Initial() | |
{ | |
for (llt i = 0; i <= N; ++i) | |
edge[i].clear(); | |
memset(flow, 0, sizeof(flow)); | |
} | |
llt MCMF(llt S, llt T) | |
{ | |
llt max_flow = 0; | |
llt min_cost = 0; | |
while (SPFA(S, T)) { | |
llt ff = FindMinFlow(S, T); | |
UpdateFlow(S, T, ff); | |
max_flow += ff; | |
min_cost += (ff * dis[T]); | |
} | |
if (max_flow != D) return -1; | |
else return min_cost; | |
} | |
bool SPFA(llt S, llt T) | |
{ | |
fill(begin(dis), end(dis), INF); | |
dis[S] = 0; | |
queue<int> Q; | |
bool inQueue[105] = {0}; | |
Q.push(S); | |
inQueue[S] = true; | |
while (!Q.empty()) { | |
llt u = Q.front(); | |
inQueue[u] = false; | |
Q.pop(); | |
for (llt v : edge[u]) { | |
if (flow[v][u] > 0 && dis[u] + (-cost[v][u]) < dis[v]) { | |
dis[v] = dis[u] + (-cost[v][u]); | |
pre[v] = u; | |
if (!inQueue[v]) {inQueue[v] = true; Q.push(v);} | |
} | |
else if (cap[u][v] > flow[u][v] && dis[u] + cost[u][v] < dis[v]) { | |
dis[v] = dis[u] + cost[u][v]; | |
pre[v] = u; | |
if (!inQueue[v]) {inQueue[v] = true; Q.push(v);} | |
} | |
} | |
} | |
if (dis[T] == INF) return false; | |
else return true; | |
} | |
llt FindMinFlow(llt S, llt T) | |
{ | |
llt bottleneck = INF; | |
for (llt u = T; u != S; u = pre[u]) | |
bottleneck = min(bottleneck, cap[pre[u]][u] - flow[pre[u]][u]); | |
return bottleneck; | |
} | |
void UpdateFlow(llt S, llt T, llt bottleneck) | |
{ | |
for (llt u = T; u != S; u = pre[u]) { | |
flow[pre[u]][u] += bottleneck; | |
flow[u][pre[u]] -= bottleneck; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment