POJ 2135 Farm Tour(最小费用最大流)
Description
To show off his farm in the best way, he walks a tour that starts at his house, potentially travels through some fields, and ends at the barn. Later, he returns (potentially through some fields) back to his house again.
He wants his tour to be as short as possible, however he doesn't want to walk on any given path more than once. Calculate the shortest tour possible. FJ is sure that some tour exists for any given farm.
Input
* Lines 2..M+1: Three space-separated integers that define a path: The starting field, the end field, and the path's length.
Output
题目大意:给一个n个点m条边的无向图,求从1走到n再从n走到1的最短路径,要求边不重复。
思路:建立一个附加源点S,连一条边到点1,容量为2,费用为0;建立一个附加汇点T,从n连一条边到T,容量为2,费用为0;对于每条边u、v,连一条边u到v,容量为1,费用为距离,再连一条边v到u,容量为1,费用为距离。最小费用最大流为答案。
建图正确性略微说明:可以考虑两次从1走到n,边不重复,那么建图流两个流量从源点到汇点,最小的费用就保证了距离最短。由于边长度为非负数,那么最小花费一定不会是一条路径从u到v,另一条路径从v到u,如果这样走了两次,还不如两条路径都不经过u-v,都走另外一条路的后继路径(不要跟我说长度是0怎么破)
PS:忘了改数组大小又TLE了一次T_T,怎么老是忘
#include <cstdio>
#include <cstring>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std; const int MAXV = ;
const int MAXE = ;
const int INF = 0x7f7f7f7f; struct SPFA_COST_FLOW {
bool vis[MAXV];
int head[MAXV], dis[MAXV], pre[MAXV];
int to[MAXE], next[MAXE], cost[MAXE], flow[MAXE];
int n, st, ed, ecnt; void init() {
memset(head, , sizeof(head));
ecnt = ;
} void add_edge(int u, int v, int c, int w) {
to[ecnt] = v; flow[ecnt] = c; cost[ecnt] = w; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; flow[ecnt] = ; cost[ecnt] = -w; next[ecnt] = head[v]; head[v] = ecnt++;
} bool spfa() {
memset(vis, , sizeof(vis));
memset(dis, 0x7f, sizeof(dis));
queue<int> que; que.push(st);
vis[st] = true; dis[st] = ;
while(!que.empty()) {
int u = que.front(); que.pop();
vis[u] = false;
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(flow[p] && dis[v] > dis[u] + cost[p]) {
dis[v] = dis[u] + cost[p];
pre[v] = p;
if(!vis[v]) {
vis[v] = true;
que.push(v);
}
}
}
}
return dis[ed] < INF;
} int maxFlow, minCost; int min_cost_flow(int ss, int tt, int nn) {
st = ss, ed = tt, n = nn;
maxFlow = minCost = ;
while(spfa()) {
minCost += dis[ed];
int u = ed, tmp = INF;
while(u != st) {
tmp = min(tmp, flow[pre[u]]);
u = to[pre[u] ^ ];
}
u = ed;
while(u != st) {
flow[pre[u]] -= tmp;
flow[pre[u] ^ ] += tmp;
u = to[pre[u] ^ ];
}
maxFlow += tmp;
}
return minCost;
}
} G; int n, m; int main() {
scanf("%d%d", &n, &m);
G.init();
int ss = n + , tt = n + ;
while(m--) {
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
G.add_edge(u, v, , c);
G.add_edge(v, u, , c);
}
G.add_edge(ss, , , );
G.add_edge(n, tt, , );
printf("%d\n", G.min_cost_flow(ss, tt, tt));
}
POJ 2135 Farm Tour(最小费用最大流)的更多相关文章
- poj 2135 Farm Tour 最小费用最大流建图跑最短路
题目链接 题意:无向图有N(N <= 1000)个节点,M(M <= 10000)条边:从节点1走到节点N再从N走回来,图中不能走同一条边,且图中可能出现重边,问最短距离之和为多少? 思路 ...
- POJ 2135 Farm Tour [最小费用最大流]
题意: 有n个点和m条边,让你从1出发到n再从n回到1,不要求所有点都要经过,但是每条边只能走一次.边是无向边. 问最短的行走距离多少. 一开始看这题还没搞费用流,后来搞了搞再回来看,想了想建图不是很 ...
- poj 2351 Farm Tour (最小费用最大流)
Farm Tour Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17230 Accepted: 6647 Descri ...
- [poj] 1235 Farm Tour || 最小费用最大流
原题 费用流板子题. 费用流与最大流的区别就是把bfs改为spfa,dfs时把按deep搜索改成按最短路搜索即可 #include<cstdio> #include<queue> ...
- POJ2135 Farm Tour —— 最小费用最大流
题目链接:http://poj.org/problem?id=2135 Farm Tour Time Limit: 1000MS Memory Limit: 65536K Total Submis ...
- TZOJ 1513 Farm Tour(最小费用最大流)
描述 When FJ's friends visit him on the farm, he likes to show them around. His farm comprises N (1 &l ...
- Farm Tour(最小费用最大流模板)
Farm Tour Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 18150 Accepted: 7023 Descri ...
- POJ 2135 Farm Tour (费用流)
[题目链接] http://poj.org/problem?id=2135 [题目大意] 有一张无向图,求从1到n然后又回来的最短路 同一条路只能走一次 [题解] 题目等价于求从1到n的两条路,使得两 ...
- poj 2135 Farm Tour 最小费最大流
inf开太小错了好久--下次还是要用0x7fffffff #include<stdio.h> #include<string.h> #include<vector> ...
- POJ 2135 Farm Tour (网络流,最小费用最大流)
POJ 2135 Farm Tour (网络流,最小费用最大流) Description When FJ's friends visit him on the farm, he likes to sh ...
随机推荐
- data-ng-model 指令
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- LeetCode8.字符串转换整数(atoi) JavaScript
请你来实现一个 atoi 函数,使其能将字符串转换成整数. 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止. 当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之 ...
- Python学习之路——基础2(含深浅拷贝)
逻辑运算符:not and or 等同于c/c++中的 !.&&.||,除了写法上的不同,实际原理是一样的. 运算也遵循短路原则.由于Python本身不支持++/--操作符,所以避 ...
- Spring知识点总结(三)之Spring DI
1. IOC(DI) - 控制反转(依赖注入) 所谓的IOC称之为控制反转,简单来说就是将对象的创建的权利及对象的生命周期的管理过程交由Spring框架来处理,从此在开发过程中不再需要关注对象的创建和 ...
- Python基础—08-函数使用(02)
函数使用 生成器 使用场景: 在使用列表时,很多时候我们都不会一下子使用全部的数据,通常都是一个一个使用,但是数据量较小的时候,对于内存的占用可以不用过于关心:但是当数据量较大时,就会出现内存使用突然 ...
- SQL中 decode() 函数介绍
decode() 函数的语法: Select decode(columnname,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值) From talbename Where … 其中:c ...
- 【CodeForces 915 C】Permute Digits(思维+模拟)
You are given two positive integer numbers a and b. Permute (change order) of the digits of a to con ...
- 用户交互input
input() 函数 接收到的都是str,如果输入为数字,打印结果想进行运算,此时需要转义.语法:内容=input("提示信息")这里可以直接获取到用户输入的内容. a = inp ...
- sql sever 基础 建表
---恢复内容开始--- SQL Sever 基础以创建银行数据库bankDB为案例 1.创建数据库 1-1 创建文件夹用以存放数据库 1-2 创建建库bankDB 2.创建数据库 2-1.创建用户信 ...
- rhel6.4 根目录扩容
状况:根目录容量不足 解决:扩容根目录 ====================================================== 解决步骤: 1. 将新的磁盘加入服务器 2. 使用 ...