热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

POJ2135FarmTour(最小费用最大流模板题)

FarmTourTimeLimit:1000MSMemoryLimit:65536KTotalSubmissions:17273Accepted:6670DescriptionWh


Farm Tour
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 17273   Accepted: 6670

Description

When FJ's friends visit him on the farm, he likes to show them around. His farm comprises N (1 <= N <= 1000) fields numbered 1..N, the first of which contains his house and the Nth of which contains the big barn. A total M (1 <= M <= 10000) paths that connect the fields in various ways. Each path connects two different fields and has a nonzero length smaller than 35,000. 

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

* Line 1: Two space-separated integers: N and M. 

* Lines 2..M+1: Three space-separated integers that define a path: The starting field, the end field, and the path's length. 

Output

A single line containing the length of the shortest tour. 

Sample Input

4 5
1 2 1
2 3 1
3 4 1
1 3 2
2 4 2

Sample Output

6

Source

给出一个无向图,其中有n个点,m条边,要从1号区域走到n号区域,去的时候和回来的时候不能走一条重复的边。问这一去一回的最小花费。


思路:


首先是建边。因为是无向图,所以:

那么一去一回,其实可以考虑为两次去。

①每一次加入的边,都要双向建立,费用流沿用了最大流中的退回边,正向边建立的费用是w.退回边建立的费用是-w。因为要求的是每一条边只经过一次不重复,那么其流量限制就是1.

②建立S源点连入1号节点,没有花费,流量为2。表示要去两次N号节点。

②建立T汇点,从N号节点连入,同样没有花费,流量为2,表示要走到N号节点两次。



#include 
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 1e3 + 7;
const int maxv = 200005;
const int INF = 0x3f3f3f3f;
int head[maxn], dis[maxn], path[maxn], pre[maxn], book[maxn] , n, m, s, t, k, sum;
struct node
{
int v, w, f, next, cnt;
}edge[3000005];
void addEdge(int u, int v, int w, int f)
{
edge[k].v = v;
edge[k].w = w;
edge[k].f = f;
edge[k].cnt = k;
edge[k].next = head[u];
head[u] = k++;
edge[k].v = u;
edge[k].w = -w;
edge[k].f = 0;
edge[k].cnt = k;
edge[k].next = head[v];
head[v] = k++;
}
int spfa()
{
queue q;
q.push(s);
memset(pre, -1, sizeof(pre));
memset(path, -1, sizeof(path));
for(int i = 1; i <= t; i++) dis[i] = INF;
dis[s] = 0;
memset(book, 0, sizeof(book));
book[s] = 1;
while(!q.empty())
{
int u = q.front();
q.pop();
book[u] = 0;
for(int i = head[u]; i != -1; i = edge[i].next)
{
int to = edge[i].v;
int w = edge[i].w;
int f = edge[i].f;
if(f && dis[to] > dis[u] + w)
{
dis[to] = dis[u] + w;
pre[to] = u;
path[to] = edge[i].cnt;
if(!book[to])
{
q.push(to);
book[to] = 1;
}
}
}
}
if(dis[t] != INF) return 1;
else return 0;
}
void Min_costflow()
{
int ans = 0;
int maxflow = 0;
while(spfa())
{
int minx = INF;
for(int i = t; i != s; i = pre[i])
{
minx = min(minx, edge[path[i]].f);
}
maxflow += minx;
ans += dis[t]*minx;
for(int i = t; i != s; i = pre[i])
{
edge[path[i]].f -= minx;
edge[path[i]^1].f += minx;
}
}
printf("%d\n", ans);
}
int main()
{
while(~scanf("%d%d", &n, &m))
{
s = 0, t = n+1, k = 0;
memset(head, -1, sizeof(head));
int x, y, z;
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d", &x, &y, &z);
addEdge(x, y, z, 1);
addEdge(y, x, z, 1);
}
addEdge(s, 1, 0, 2);
addEdge(n, t, 0, 2);
Min_costflow();
}
return 0;
}



推荐阅读
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文讨论了一个数列求和问题,该数列按照一定规律生成。通过观察数列的规律,我们可以得出求解该问题的算法。具体算法为计算前n项i*f[i]的和,其中f[i]表示数列中有i个数字。根据参考的思路,我们可以将算法的时间复杂度控制在O(n),即计算到5e5即可满足1e9的要求。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • 本文介绍了SPOJ2829题目的解法及优化方法。题目要求找出满足一定条件的数列,并对结果取模。文章详细解释了解题思路和算法实现,并提出了使用FMT优化的方法。最后,对于第三个限制条件,作者给出了处理方法。文章最后给出了代码实现。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
author-avatar
疯子zls_565
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有