题意:给一个无向图,FJ要从1号点出发到达n号点,再返回到1号点,但是路一旦走过了就会销毁(即回去不能经过),每条路长度不同,那么完成这趟旅行要走多长的路?(注:会有重边,点号无序,无向图!)

思路:

  有重边,要用邻接表。所给的每条边都要变成4条有向边!否则可能一开始就到达不了终点了。最后要再加上一个源点和汇点,容量cap(源点,1)=2,指定只能走两次,再规定其他所给的边的容量是1就行了,当边被走过了,就自动增加了流,也就走不了了。

  解释看代码更清晰。

 //#pragma comment(linker,"/STACK:102400000,102400000")
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
//#include <bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
#define INF 0x7f7f7f7f
using namespace std;
const int N=+;
vector<int> vect[N];
struct node
{
int from;
int to;
int cost;
int cap;
int flow;
}edge[N*]; //边数是4*M的大小 int edge_num; //边的上限
int f[N]; //流
int path[N]; //记录路径
int c[N]; //记录费用
bool in[N]; //是否在queue中 void add_node(int a, int b, int c, int ca, int fl)
{
edge[edge_num].from=a;
edge[edge_num].to=b;
edge[edge_num].cost=c;
edge[edge_num].cap=ca;
edge[edge_num].flow=fl;
vect[a].push_back(edge_num++);
} LL spfa(int s,int e)
{
deque<int> que;
que.push_back(s);
c[s]=;
f[s]=INF;
in[s]=;
while(!que.empty())
{
int x=que.front();
que.pop_front();
in[x]=;
for(int i=; i<vect[x].size(); i++)
{
node t=edge[vect[x][i]];
if(t.cap>t.flow && c[t.to]>c[t.from]+t.cost) //能流过,且费用更小即可更新。
{
path[t.to]=vect[x][i]; //记边号,方便更新flow
c[t.to]=c[t.from]+t.cost; //更新cost,相当于距离
f[t.to]=min(f[t.from], t.cap-t.flow);
if(!in[t.to])
{
que.push_back(t.to);
in[t.to]=;
}
}
}
}
return c[e];
} int m; int mcmf(int s, int e)
{
LL ans=;
while()
{
memset(f, , sizeof(f));
memset(c, 0x7f, sizeof(c));
memset(in, , sizeof(in));
memset(path, , sizeof(path)); int tmp=spfa(s, e);
if(tmp==INF) return ans;
ans+=tmp*f[e]; //这是最小费用。注:每次的流可能不是1。 int ed=e;
while(ed!=s)
{
int en=path[ed];
edge[en].flow+=f[e];
edge[en^].flow-=f[e];
ed=edge[en].from;
//cout<<edge[en].from<<"-"<<edge[en].to<<endl;
}
}
} int main()
{
freopen("input.txt", "r", stdin);
int n, a, b, c;
while(~scanf("%d%d", &n, &m))
{
for(int i=n*; i>=; i--) vect[i].clear();
edge_num=;
for(int i=; i<m; i++)
{
scanf("%d%d%d",&a,&b,&c);
add_node(a,b,c,,); //4条有向边。
add_node(b,a,-c,,); add_node(b,a,c,,);
add_node(a,b,-c,,);
}
add_node(,,,,); //加多2条边
add_node(,,,,); //加这条无意义,但是更新flow时更方便
add_node(n,n+,,,);
add_node(n+,n,,,); printf("%lld\n",mcmf(, n+));
} return ;
}

AC代码

POJ 2135 Farm Tour(最小费用最大流,变形)的更多相关文章

  1. poj 2135 Farm Tour 最小费用最大流建图跑最短路

    题目链接 题意:无向图有N(N <= 1000)个节点,M(M <= 10000)条边:从节点1走到节点N再从N走回来,图中不能走同一条边,且图中可能出现重边,问最短距离之和为多少? 思路 ...

  2. POJ 2135 Farm Tour [最小费用最大流]

    题意: 有n个点和m条边,让你从1出发到n再从n回到1,不要求所有点都要经过,但是每条边只能走一次.边是无向边. 问最短的行走距离多少. 一开始看这题还没搞费用流,后来搞了搞再回来看,想了想建图不是很 ...

  3. poj 2351 Farm Tour (最小费用最大流)

    Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17230   Accepted: 6647 Descri ...

  4. [poj] 1235 Farm Tour || 最小费用最大流

    原题 费用流板子题. 费用流与最大流的区别就是把bfs改为spfa,dfs时把按deep搜索改成按最短路搜索即可 #include<cstdio> #include<queue> ...

  5. POJ2135 Farm Tour —— 最小费用最大流

    题目链接:http://poj.org/problem?id=2135 Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submis ...

  6. 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 ...

  7. Farm Tour(最小费用最大流模板)

    Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18150   Accepted: 7023 Descri ...

  8. POJ 2135 Farm Tour (费用流)

    [题目链接] http://poj.org/problem?id=2135 [题目大意] 有一张无向图,求从1到n然后又回来的最短路 同一条路只能走一次 [题解] 题目等价于求从1到n的两条路,使得两 ...

  9. poj 2135 Farm Tour 最小费最大流

    inf开太小错了好久--下次还是要用0x7fffffff #include<stdio.h> #include<string.h> #include<vector> ...

  10. POJ 2135 Farm Tour (网络流,最小费用最大流)

    POJ 2135 Farm Tour (网络流,最小费用最大流) Description When FJ's friends visit him on the farm, he likes to sh ...

随机推荐

  1. win8安装python环境和pip & easy_install工具

    最近在学python,2.7.6的版本 首先安装python2.7 官网下载地址https://www.python.org/downloads/ 下载相应版本即可,应该是一个msi的文件,默认安装到 ...

  2. Flex读文本文件

    布局: <s:Group id="> <s:Rect width="100%" height="100%"> <s:fi ...

  3. hdu 4641 K-string SAM的O(n^2)算法 以及 SAM+并查集优化

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4641 题意:有一个长度为n(n < 5e4)的字符串,Q(Q<=2e5)次操作:操作分为:在末 ...

  4. 【cheerio】nodejs的抓取页面模块

    http://baike.baidu.com/link?url=8V1CZsEzNE05ujOzISquom_pvFj16sWu1rRb8js11pmd9HNq7ePW_aKfG9oyXj6Txuu5 ...

  5. 浅淡Windows7 32位与64位/x86与x64的区别

    看到有很多会员问到底是选Windows7 x86,还是选x64.这里简单的谈一下这这两种系统的区别. 简单的说x86代表32位操作系统  x64代表64位操作系统. 简单的判断电脑是否支持64位操作系 ...

  6. 深入js的面向对象学习篇(封装是一门技术和艺术)——温故知新(二)

    下面全面介绍封装和信息隐藏. 通过将一个方法或属性声明为私用的,可以让对象的实现细节对其它对象保密以降低对象之间的耦合程度,可以保持数据的完整性并对其修改方式加以约束.在代码有许多人参与设计的情况下, ...

  7. jmp && call && ret 特权级转移 & 进程调度

    ①jmp是不负责任的调度,不保存任何信息,不考虑会回头.跳过去就什么也不管了.②call,保存eip等,以便程序重新跳回.ret是call的逆过程,是回头的过程.这都是cpu固有指令,因此要保存的信息 ...

  8. Navicat for mysql 远程连接 mySql数据库10061、1045错误问题 (转)

    远程使用Navicat for mysql 客户端软件连接 mySql数据时,连接出现 2003-Can’t connect to MySQL on ’192.168.1.2’(10061)错误时,是 ...

  9. HDU1796+容斥原理

    给定n和m个数,询问在小于n的数中 有多少个能整除m中的某个数.. 容斥原理. PS:注意64位整数! /* 容斥原理 */ #include<stdio.h> #include<s ...

  10. POJ3204+DInic+maxflow

    Dinic+maxflow题意:找这样一种边的个数,就是增加该边的容量,可以使得最大流变大思路:求maxflow,再枚举流量为0的边,增加容量,看是否能找到增广路径. /* Dinic+maxflow ...