sgu252:Railway Communication(费用流)
2015-06-05 05:06
435 查看
题目大意:
~~~~~~在有向无环图中求出一个最小路径覆盖,每条边有边权,满足这个最小路径覆盖是所有最小路径覆盖中权值和最小的。
分析:
~~~~~~最小路径覆盖套个费用流完事。
AC code:
~~~~~~在有向无环图中求出一个最小路径覆盖,每条边有边权,满足这个最小路径覆盖是所有最小路径覆盖中权值和最小的。
分析:
~~~~~~最小路径覆盖套个费用流完事。
AC code:
[code]#include <cstdio> #include <cmath> #include <cstdlib> #include <cstring> #include <cctype> #include <algorithm> #include <string> #include <sstream> #include <iostream> #include <map> #include <set> #include <list> #include <stack> #include <queue> #include <vector> #define pii pair<int,int> #define pb push_back #define mp make_pair #define x first #define y second #define A(p) ((p)*2-1) #define B(p) (A(p)+1) #define inv(p) ((((p)-1)^1)+1) typedef long long LL; typedef double DB; typedef long double LD; using namespace std; const int MAXN = 209; const int MAXM = 3009; const int INF = 0x3f3f3f3f; int n, m; struct Net { int size; int head[MAXN]; int to[MAXM]; int f[MAXM], c[MAXM]; int ne[MAXM]; Net() {size = 1;} void add_edge(int u, int v, int flow, int cost) { to[size] = v, c[size] = cost, f[size] = flow, ne[size] = head[u], head[u] = size++; to[size] = u, c[size] = -cost, f[size] = 0, ne[size] = head[v], head[v] = size++; } }G; int s, t; int dis[MAXN]; int pre[MAXN]; int pree[MAXN]; int pref[MAXN]; int prec[MAXN]; bool vis[MAXN]; int to[MAXN]; int deg[MAXN]; vector<int> path; bool spfa(int s, int t) { queue<int> q; memset(dis, INF, sizeof dis);dis[s] = 0; memset(vis, false, sizeof vis);vis[s] = true; memset(pre, 0, sizeof pre);q.push(s); memset(pree, 0, sizeof pree); memset(pref, 0, sizeof pref); memset(prec, 0, sizeof prec); while(!q.empty()) { int now = q.front();q.pop();vis[now] = false; for(int i = G.head[now]; i; i = G.ne[i]) { int to = G.to[i]; if(G.f[i] && dis[now]+G.c[i] < dis[to]) { dis[to] = dis[now]+G.c[i]; pre[to] = now, pref[to] = G.f[i], prec[to] = G.c[i], pree[to] = i; if(!vis[to]) { vis[to] = true; q.push(to); } } } } return dis[t] < INF; } pii calc(int s, int t) { int rf = INF, rc = 0; for(int i = t; i != s; i = pre[i]) rf = min(rf, pref[i]); for(int i = t; i != s; i = pre[i]) { G.f[pree[i]] -= rf, G.f[inv(pree[i])] += rf; rc += rf*prec[i]; } return mp(rf, rc); } void operator += (pii &a, const pii &b) {a.x+=b.x, a.y+=b.y;} pii maxflow_mincost(int s, int t) { pii ret; while(spfa(s, t)) ret += calc(s, t); return ret; } int main() { #ifndef ONLINE_JUDGE freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); #endif scanf("%d%d", &n, &m); for(int i = 1; i <= m; ++i) { int u, v, c; scanf("%d%d%d", &u, &v, &c); G.add_edge(A(u), B(v), INF, c); } s = 2*n+1, t = s+1; for(int i = 1; i <= n; ++i) { G.add_edge(s, A(i), 1, 0); G.add_edge(B(i), t, 1, 0); } pii ans = maxflow_mincost(s, t); printf("%d %d\n", n-ans.x, ans.y); for(int i = 1; i <= n; ++i) for(int j = G.head[A(i)]; j; j = G.ne[j]) if(G.f[j] < INF && G.to[j] < s) { to[i] = (G.to[j]+1)>>1; deg[to[i]]++; break; } for(int i = 1; i <= n; ++i) if(!deg[i]) { int j = i; path.clear(); while(j) { path.pb(j); j = to[j]; } printf("%d", path.size()); for(int p = 0, sz = path.size(); p < sz; ++p) printf(" %d", path[p]); puts(""); } #ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout); #endif return 0; }
相关文章推荐
- Climbing Stairs
- 从main函数中argc和argv开始学习
- [LOJ 1038] Race to 1 Again
- How did your survive waiting
- TurboMail智能防御企业邮箱盗号和退信攻击
- tools:context=".MainActivity的作用
- 用libaio读写文件时遇到的问题
- UVA514 Rails
- UVA442 Matrix Chain Multiplication
- light oj 1038 - Race to 1 Again(概率dp求期望 记忆化搜索)
- rails4.2~devise邮箱测试
- hdu 5009 Paint Pearls
- HDU 2476 - String painter(区间DP)
- 【leetcode】Contains Duplicate II
- suspend() 和 resume() 方法,notify()和wait()方法区别
- Splay树(区间添加删除 | 区间翻转)——HDU 3487 Play with Chain
- sizeWithFont:constrainedToSize:转boundingRectWithSize:options:
- msdb.dbo.sp_send_dbmail 用法简介
- MacBook Air装单独win7
- Message和obtainMessage的区别