hdu 3667 (拆边 mcmf)
2013-08-17 09:24
363 查看
注意题目中 边的容量 <= 5.可以把费用权值 a *f ^2化归成 a * f2, 即第一条边费用为 1 * a, 第二条 为 (4 - 1) * a, 第三条为 (9 - 4) * a。。。。。。
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int maxn = 110; const int maxm = 25000; const int inf = 0x3f3f3f3f; const int ww[5] = {1, 3, 5, 7, 9}; struct MCMF { struct Edge { int v, c, w, next; }p[maxm << 1]; int e, head[maxn], dis[maxn], pre[maxn], cnt[maxn], sumFlow, n; bool vis[maxn]; void init(int nt) { e = 0; n = nt; memset(head, -1, sizeof(head[0]) * (n + 2)); } void addEdge(int u, int v, int c, int w) { p[e].v = v; p[e].c = c; p[e].w = w; p[e].next = head[u]; head[u] = e++; swap(u, v); p[e].v = v; p[e].c = 0; p[e].w =-w; p[e].next = head[u]; head[u] = e++; } bool spfa(int S, int T) { queue <int> q; for (int i = 0; i <= n; ++i) vis[i] = cnt[i] = 0, pre[i] = -1, dis[i] = inf; vis[S] = 1; dis[S] = 0; q.push(S); while (!q.empty()) { int u = q.front(); q.pop(); vis[u] = 0; for (int i = head[u]; i + 1; i = p[i].next) { int v = p[i].v; if (p[i].c && dis[v] > dis[u] + p[i].w) { dis[v] = dis[u] + p[i].w; pre[v] = i; if (!vis[v]) { q.push(v); vis[v] = 1; if (++cnt[v] > n) return 0; } } } } return dis[T] != inf; } int mcmf(int S, int T) { sumFlow = 0; int minFlow = 0, minCost = 0; while (spfa(S, T)) { minFlow = inf + 1; for (int i = pre[T]; i + 1; i = pre[ p[i ^ 1].v ]) minFlow = min(minFlow, p[i].c); sumFlow += minFlow; for (int i = pre[T]; i + 1; i = pre[ p[i ^ 1].v ]) p[i].c -= minFlow, p[i ^ 1].c += minFlow; minCost += dis[T] * minFlow; } return minCost; } void build(int nt, int mt, int kt) { init(nt); addEdge(0, 1, kt, 0); int u, v, c, w; for (int i = 0; i < mt; ++i) { scanf("%d%d%d%d", &u, &v, &w, &c); for (int j = 0; j < c; ++j) addEdge(u, v, 1, w * ww[j]); } } void solve(int nt, int mt, int kt) { build(nt, mt, kt); int ans = mcmf(0, n); // cout <<"sumFlow = " << sumFlow << " cost = " << ans << endl; if (sumFlow != kt) printf("-1\n"); else printf("%d\n", ans); } }my; int main() { int n, m, k; while (~scanf("%d%d%d", &n, &m, &k)) my.solve(n, m, k); return 0; }
相关文章推荐
- hdu 3667 拆边费用流
- HDU 3667 Transportation(最小费用最大流)
- 最小费用最大流 hdu 3667
- HDU 3667 Transportation (最小费用最大流)
- HDU 3667 Transportation(网络流之费用流)
- ★ HDU 3667 费用与流量平方成正比的最小流
- HDU -- 3667 Transportation(最小费用最大流 )
- hdu 3667 Transportation 费用流
- HDU 3667 Transportation(建边技巧+最小费用最大流)
- HDU 3667 Transportation(最小费用最大流)
- POJ 3667 & HDU 3308 & HDU 3397 线段树的区间合并
- hdu 3667(最小费用最大流+拆边)
- HDU 4862 Jump(最小费用最大流-mcmf)
- POJ 3667 Hotel & HDU 2871 Memory Control 线段树区间合并
- POJ 2195 && HDU 1533 Going Home(最小费用最大流-mcmf)
- hdu 3667 线段树区间合并
- HDU 3667 Transportation
- HDU-3667 Hetol 线段树 区间合并
- HDU 3667
- hdu 3667 (费用流,拆边)