uva 1658 Admiral (最小费最大流)
来源:互联网 发布:计算机 数学 知乎 编辑:程序博客网 时间:2024/05/01 02:46
uva 1658 Admiral
题目大意:在图中找出两条没有交集的线路,要求这两条线路的费用最小。
解题思路:还是拆点建图的问题。首先每个点都要拆成两个点,例如a点拆成a->a’。起点和终点的两点间的容量为2费用为0,保证了只找出两条线路。其余点的容量为1费用为0,保证每点只走一遍,两条线路无交集。然后根据题目给出的要求继续建图。每组数据读入a, b, c, 建立a’到b的边容量为1, 费用为c。图建完之后,用bellman-ford来实现MCMF。
#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <cstdlib>#include <queue>using namespace std;typedef long long ll;const int N = 2005;const int INF = 0x3f3f3f3f;int n, m, s, t;int a[N], pre[N], d[N], inq[N]; struct Edge{ int from, to, cap, flow; ll cos;};vector<Edge> edges;vector<int> G[N];void init() { for (int i = 0; i < 2 * n; i++) G[i].clear(); edges.clear();}void addEdge(int from, int to, int cap, int flow, ll cos) { edges.push_back((Edge){from, to, cap, 0, cos}); edges.push_back((Edge){to, from, 0, 0, -cos}); int m = edges.size(); G[from].push_back(m - 2); G[to].push_back(m - 1);}void input() { addEdge(1, n + 1, 2, 0, 0); for (int i = 2; i <= n - 1; i++) { addEdge(i, i + n, 1, 0, 0); } addEdge(n, 2 * n, 2, 0, 0); int u, v; ll c; for (int i = 0; i < m; i++) { scanf("%d %d %lld", &u, &v, &c); addEdge(u + n, v, 1, 0, c); }}int BF(int s, int t, int& flow, ll& cost) { queue<int> Q; memset(inq, 0, sizeof(inq)); memset(a, 0, sizeof(a)); memset(pre, 0, sizeof(pre)); for (int i = 0; i <= 2 * n + 1; i++) d[i] = INF; d[s] = 0; a[s] = INF; inq[s] = 1; int flag = 1; pre[s] = 0; Q.push(s); while (!Q.empty()) { int u = Q.front(); Q.pop(); inq[u] = 0; for (int i = 0; i < G[u].size(); i++) { Edge &e = edges[G[u][i]]; if (e.cap > e.flow && d[e.to] > d[u] + e.cos) { d[e.to] = d[u] + e.cos; a[e.to] = min(a[u], e.cap - e.flow); pre[e.to] = G[u][i]; if (!inq[e.to]) { inq[e.to] = 1; Q.push(e.to); } } } flag = 0; } if (d[t] == INF) return 0; flow += a[t]; cost += (ll)d[t] * (ll)a[t]; for (int u = t; u != s; u = edges[pre[u]].from) { edges[pre[u]].flow += a[t]; edges[pre[u]^1].flow -= a[t]; } return 1;}int MCMF(int s, int t, ll& cost) { int flow = 0; cost = 0; while (BF(s, t, flow, cost)); return flow;}int main() { while (scanf("%d %d", &n, &m) == 2) { s = 1, t = 2 * n; ll cost; init(); input(); MCMF(s, t, cost); printf("%lld\n", cost); } return 0;}
0 0
- uva 1658 Admiral 最小费最大流
- uva 1658 Admiral (最小费最大流)
- UVA 1658 Admiral——拆点法+最小费最大流
- UVa 1658 Admiral (最小费用最大流、拆点法)
- 最小费最大流,拆点法(海军上将 uva 1658)
- UVA 1658 - Admiral (拆点+最小费用流)
- UVA 1658 Admiral(拆点+最小费用流)
- UVA 1658 Admiral (最小费用流)
- uva 10806 Dijkstra, Dijkstra. (最小费最大流)
- uva 10806(最大流最小费)
- uva 10746(最大流最小费)
- uva 10594(最大流最小费)
- 最小费最大流,最小权最大匹配,拆点法(最优巴士路线设计 uva 1349)
- uva1658 Admiral 最小费用最大流
- 最小费用最大流--uva1658 Admiral
- uva 10746 Crime Wave - The Sequel (最小费最大流)
- uva 10594 Data Flow (最小费最大流+题目给的数据有错)
- UVA 1658Admiral(拆点+费用流)
- prepareCall()执行存储过程
- Leetcode: Lowest Common Ancestor of a Binary Tree
- ubuntu 下解决“no java virtual machine was found after searching the following locations:” 方法
- struts拦截器
- 鼠标悬停在按钮上延时响应OnMouseHover、OnMouseMove和OnMouseLeave
- uva 1658 Admiral (最小费最大流)
- Android-真机调试时LogCat不显示的问题
- iOS图片拉伸_小图变大图
- uva 11178 Morley's Theorem
- sgu288:Best Tournament Schedule(构造)
- codevs1029
- unix回射服务器,客服端
- vb快速排序源代码
- Java语言编写计算器(简单的计算器)