POJ2135
来源:互联网 发布:长沙蓝狐网络 编辑:程序博客网 时间:2024/05/07 19:05
题目链接:
http://poj.org/problem?id=2135
题目大意:
现在有 N 个节点,有M条边,要从 1 走到 N 然后再回到 1 。要求走的边不能重复,求最短路径。
解题过程:
之前看了最小费用最大流然后一直没有做题,于是找了一个模板题来刷,对着板子敲上去居然一次AC,然后又改了下最短路的算法,AC。
题目分析:
算是一个隐含的最小费用最大流,设每条边的容量为1,花费为路径长度。那么所求的就是一个从起点 1 到终点 N 流量为 2 的流的最小费用流。
这里用的是最短增广路算法。
AC代码:
#include <cstdio>#include <vector>#include <queue>#include <cstring>using namespace std;const int MAX = 1123, INF = 0x3f3f3f3f;int N, M;struct Node{ int to, cap, cost, rev; Node(int to, int cap, int cost, int rev):to(to), cap(cap), cost(cost), rev(rev){}};vector<Node> edge[MAX];int dist[MAX], vis[MAX], prevv[MAX], preve[MAX];void add_edge(int from, int to, int cap, int cost) { edge[from].push_back(Node(to, cap, cost, edge[to].size())); edge[to].push_back(Node(from, 0, -cost, edge[from].size()-1));}int min_cost_flow(int s, int t, int f) { int rst = 0; //循环到到达了f流量 while (f > 0) { memset(dist, INF, sizeof(dist)); queue<int> q; q.push(s); vis[s] = 1; dist[s] = 0; while (!q.empty()) { int u = q.front(); for (int i = 0; i < edge[u].size(); i++) { Node& e = edge[u][i]; if (e.cap > 0 && dist[e.to] > dist[u] + e.cost) { dist[e.to] = dist[u] + e.cost; prevv[e.to] = u; preve[e.to] = i; if (!vis[e.to]) { q.push(e.to); vis[e.to] = 1; } } } q.pop(); vis[u] = 0; } if (dist[t] == INF) return -1; //最路径上最小流量 int d = f; for (int u = t; u != s; u = prevv[u]) { d = min(d, edge[prevv[u]][preve[u]].cap); } //剩余的流量 f -= d; //计算费用 rst += d * dist[t]; //修改路上所经过的边的容量 for (int u = t; u != s; u = prevv[u]) { Node& e = edge[prevv[u]][preve[u]]; e.cap -= d; edge[u][e.rev].cap += d; } } return rst;}int main() { scanf("%d %d", &N, &M); for (int i = 0; i < M; i++) { int from, to, cost; scanf("%d %d %d", &from, &to, &cost); add_edge(from, to, 1, cost); add_edge(to, from, 1, cost); } //求流量为2的最小费用 int ans = min_cost_flow(1, N, 2); printf("%d\n", ans);}
居然可以AC的Dijstra代码:
#include <cstdio>#include <vector>#include <queue>#include <cstring>using namespace std;const int MAX = 1123, INF = 0x3f3f3f3f;int N, M;struct Node{ int to, cap, cost, rev; Node(int to, int cap, int cost, int rev):to(to), cap(cap), cost(cost), rev(rev){}};vector<Node> edge[MAX];int dist[MAX], vis[MAX], prevv[MAX], preve[MAX];void add_edge(int from, int to, int cap, int cost) { edge[from].push_back(Node(to, cap, cost, edge[to].size())); edge[to].push_back(Node(from, 0, -cost, edge[from].size()-1));}int min_cost_flow(int s, int t, int f) { int rst = 0; while (f > 0) { memset(dist, INF, sizeof(dist)); queue<int> q; q.push(s); vis[s] = 1; dist[s] = 0; while (!q.empty()) { int u = q.front(); for (int i = 0; i < edge[u].size(); i++) { Node& e = edge[u][i]; if (e.cap > 0 && dist[e.to] > dist[u] + e.cost) { dist[e.to] = dist[u] + e.cost; prevv[e.to] = u; preve[e.to] = i; if (!vis[e.to]) { q.push(e.to); vis[e.to] = 1; } } } q.pop(); vis[u] = 0; } if (dist[t] == INF) return -1; int d = f; for (int u = t; u != s; u = prevv[u]) { d = min(d, edge[prevv[u]][preve[u]].cap); } f -= d; rst += d * dist[t]; for (int u = t; u != s; u = prevv[u]) { Node& e = edge[prevv[u]][preve[u]]; e.cap -= d; edge[u][e.rev].cap += d; } } return rst;}int main() { scanf("%d %d", &N, &M); for (int i = 0; i < M; i++) { int from, to, cost; scanf("%d %d %d", &from, &to, &cost); add_edge(from, to, 1, cost); add_edge(to, from, 1, cost); } int ans = min_cost_flow(1, N, 2); printf("%d\n", ans);}
阅读全文
1 0
- poj2135
- POJ2135
- poj2135
- POJ2135
- poj2135
- POJ2135
- poj2135
- poj2135 - Farm Tour
- poj2135 Farm Tour
- poj2135--Farm Tour
- poj2135 Farm Tour
- poj2135(模板题)
- POJ2135 Farm Tour (mcmf)
- POJ2135-Farm Tour
- 【poj2135】Farm Tour
- POJ2135 Farm Tour
- POJ2135: Farm Tour 题解
- POJ2135 Farm Tour
- 对抗样本和对抗网络
- Android 使用View的旋转实现漂亮的动画效果
- 如何在官网下载 >>>>红帽企业版linux
- C#:IComparable和ICompare
- Codeigniter提示:Undefined property: XXXX::$db的解决方法
- POJ2135
- Linux使用动态ip(dhcp)切换成静态ip后无法联网的问题
- 34. Search for a Range
- EOJ----足球锦标赛
- 1002.写出这个数
- Java.lang学习笔记
- 枚举排列
- java--异常总结
- 算法训练:Continuous Subarray Sum