LA 2197 Paint the Roads 费用流
2014-06-10 19:45
302 查看
传送门:LA 2197 Paint the Roads
题目大意:某国有n个城市,用m条单向道路相连。你的任务粉刷其中一些道路,使得被粉刷的道路组成一些没有公共边的回路,且每个城市恰好在其中k条回路上。被粉刷的所有道路的总长度应尽量小。
题目分析:点在回路上说明出度和入度相等,所以对所有点进行拆点。设立超级源汇,建边(s,i,k,0),(i + n,t,k,0),对所有边(i,j)建边(i,j + 1,1,w)。跑一遍最小费用最大流,如果满流则有解输出cost即可否则无解输出-1。
代码如下:
题目大意:某国有n个城市,用m条单向道路相连。你的任务粉刷其中一些道路,使得被粉刷的道路组成一些没有公共边的回路,且每个城市恰好在其中k条回路上。被粉刷的所有道路的总长度应尽量小。
题目分析:点在回路上说明出度和入度相等,所以对所有点进行拆点。设立超级源汇,建边(s,i,k,0),(i + n,t,k,0),对所有边(i,j)建边(i,j + 1,1,w)。跑一遍最小费用最大流,如果满流则有解输出cost即可否则无解输出-1。
代码如下:
#include <stdio.h> #include <string.h> #include <algorithm> #define clear(A, X) memset(A, X, sizeof A) #define min(A, B) ((A) < (B) ? (A) : (B)) using namespace std; const int maxE = 2000000; const int maxN = 256; const int oo = 0x3f3f3f3f; struct Edge{ int v, c, w, n; Edge(){} Edge(int V, int C, int W, int N) : v(V), c(C), w(W), n(N){} }; struct Node{ int l, r, w; }; Edge edge[maxE]; Node sche[maxN]; int adj[maxN], cntE; int Q[maxE], head, tail; int d[maxN], inq[maxN], cur[maxN], f[maxN]; int cost, flow, s, t; int N, M, K; void addedge(int u, int v, int c, int w){ edge[cntE] = Edge(v, c, w, adj[u]); adj[u] = cntE++; edge[cntE] = Edge(u, 0, -w, adj[v]); adj[v] = cntE++; } int spfa(){ f[s] = oo; clear(d, oo); clear(inq, 0); cur[s] = -1; d[s] = 0; head = tail = 0; Q[tail++] = s; inq[s] = 1; while(head != tail){ int u = Q[head++]; inq[u] = 0; for(int i = adj[u]; ~i; i = edge[i].n){ int v = edge[i].v, c = edge[i].c, w = edge[i].w; if(c && d[v] > d[u] + w){ d[v] = d[u] + w; f[v] = min(f[u], c); cur[v] = i; if(!inq[v]){ Q[tail++] = v; inq[v] = 1; } } } } if(d[t] == oo) return 0; flow += f[t]; cost += d[t] * f[t]; for(int i = cur[t]; ~i; i = cur[edge[i ^ 1].v]){ edge[i].c -= f[t]; edge[i ^ 1].c += f[t]; } return 1; } int MCMF(){ flow = cost = 0; while(spfa()); return cost; } void init(){ clear(adj, -1); cntE = 0; } void build(){ int u, v, w; scanf("%d%d%d", &N, &M, &K); s = N * 2; t = N * 2 + 1; for(int i = 0; i < N; ++i) addedge(s, i, K, 0), addedge(i + N, t, K, 0); for(int i = 0; i < M; ++i){ scanf("%d%d%d", &u, &v, &w); addedge(u, v + N, 1, w); } } void work(){ init(); build(); MCMF(); printf("%d\n", flow == N * K ? cost : -1); } int main(){ int T; for(scanf("%d", &T); T; --T) work(); return 0; }
相关文章推荐
- [省选前题目整理][LA 2197]Paint the Roads(费用流)
- UVALive 2197 Paint the Roads(费用流)
- UVALive - 2197 Paint the Roads(费用流)
- UvaLive 2197 Paint the Roads(费用流)
- Paint the Roads UVALive - 2197
- 【 UVALive - 2197】Paint the Roads(上下界费用流)
- uva 12092 Paint the Roads(费用流)
- UVa12092 Paint the Roads(最小费用最大流)
- uva12092 Paint the Roads
- uva 12092 - Paint the Roads(最小费用最大流)
- (intermediate) 最小费用流 UVA 12092 - Paint the Roads
- Uva-12092-Paint the Roads
- UVa:10308 Roads in the North
- ZOJ - 3781 Paint the Grid Reloaded 题解
- LA 3942 Remember the Word
- 拓扑排序(ZOJ 3780,Paint the Grid Again)
- 【POJ 2631 Roads in the North】
- ZOJ 3781 Paint the Grid Reloaded ( BFS(重点是对问题的分析) )
- ZOJ 3780 Paint the Grid Again
- ZOJ 3885 The Exchange of Items(费用流)