POJ2135 Farm Tour 最小费用流
来源:互联网 发布:java微信 api好友列表 编辑:程序博客网 时间:2024/06/05 15:16
/*
题目描述:给定一张无向图,找两条从点1到点n的不含重复边的路径,使得两条路的距离和最小
方法:其实如果想到使用最小费用流就不太难了,但关键是不容易想到......
首先按照题目中所给的边建图,每条边的容量为1,费用为给定边的长度;
源节点连向点1,容量为2,费用为0, 点n连向汇点,容量为2,费用为0,求一遍最小费用流得到答案;
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define mem(a,x) memset(a,x,sizeof(a))
using namespace std;
const int inf = 1000000000;
const int maxn = 1000 + 5;
int n,m;
typedef long long ll;
struct Edge
{
int from,to,cap,flow,cost;
};
struct MCMF
{
int n,m,s,t;
vector<Edge>edges;
vector<int>G[maxn];
int d[maxn],p[maxn],a[maxn],inq[maxn];
void init(int n)
{
this -> n = n;
for(int i=0;i<=n;i++) G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,int cap,int cost)
{
Edge e1 = {from , to , cap , 0 , cost};
Edge e2 = {to , from , 0 , 0 , -cost};
edges.push_back(e1);
edges.push_back(e2);
int m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool BellmanFord(int s,int t,int &flow , ll& cost)
{
for(int i=0;i<=n;i++){
d[i] = inf;
}
d[s] = 0; p[s] = 0; a[s] = inf;
mem(inq,0); inq[s] = 1;
queue<int>Q;
Q.push(s);
while(!Q.empty()){
int x = Q.front(); Q.pop();
inq[x] = 0;
for(int i= 0;i<G[x].size();i++){
Edge &e = edges[G[x][i]];
if(e.cap>e.flow && d[e.to]>d[x]+e.cost){
d[e.to] = d[x] + e.cost;
p[e.to] = G[x][i];
a[e.to] = min(a[x],e.cap - e.flow);
if(!inq[e.to]){
Q.push(e.to);
inq[e.to] = 1;
}
}
}
}
if(d[t]==inf) return false;
flow += a[t];
cost += (ll)a[t]*(ll)d[t];
int u = t;
while(u!=s){
edges[p[u]].flow += a[t];
edges[p[u]^1].flow -= a[t];
u = edges[p[u]].from;
}
return true;
}
ll Mincost(int s,int t,int & flow)
{
flow = 0;
ll cost = 0;
while(BellmanFord(s,t,flow,cost)) ;
return cost;
}
};
MCMF g;
int main()
{
while(scanf("%d %d",&n,&m)!=EOF){
int s , e ,length;
int source = 0 , sink = n + 1;
g.init(n+1);
for(int i=0;i<m;i++){
scanf("%d %d %d",&s,&e,&length);
g.AddEdge(s,e,1,length);
g.AddEdge(e,s,1,length);
}
g.AddEdge(source,1,2,0);
g.AddEdge(n,sink,2,0);
int flow;
ll ans1 = g.Mincost(source,sink,flow);
printf("%lld\n",ans1);
}
return 0;
}
题目描述:给定一张无向图,找两条从点1到点n的不含重复边的路径,使得两条路的距离和最小
方法:其实如果想到使用最小费用流就不太难了,但关键是不容易想到......
首先按照题目中所给的边建图,每条边的容量为1,费用为给定边的长度;
源节点连向点1,容量为2,费用为0, 点n连向汇点,容量为2,费用为0,求一遍最小费用流得到答案;
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define mem(a,x) memset(a,x,sizeof(a))
using namespace std;
const int inf = 1000000000;
const int maxn = 1000 + 5;
int n,m;
typedef long long ll;
struct Edge
{
int from,to,cap,flow,cost;
};
struct MCMF
{
int n,m,s,t;
vector<Edge>edges;
vector<int>G[maxn];
int d[maxn],p[maxn],a[maxn],inq[maxn];
void init(int n)
{
this -> n = n;
for(int i=0;i<=n;i++) G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,int cap,int cost)
{
Edge e1 = {from , to , cap , 0 , cost};
Edge e2 = {to , from , 0 , 0 , -cost};
edges.push_back(e1);
edges.push_back(e2);
int m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool BellmanFord(int s,int t,int &flow , ll& cost)
{
for(int i=0;i<=n;i++){
d[i] = inf;
}
d[s] = 0; p[s] = 0; a[s] = inf;
mem(inq,0); inq[s] = 1;
queue<int>Q;
Q.push(s);
while(!Q.empty()){
int x = Q.front(); Q.pop();
inq[x] = 0;
for(int i= 0;i<G[x].size();i++){
Edge &e = edges[G[x][i]];
if(e.cap>e.flow && d[e.to]>d[x]+e.cost){
d[e.to] = d[x] + e.cost;
p[e.to] = G[x][i];
a[e.to] = min(a[x],e.cap - e.flow);
if(!inq[e.to]){
Q.push(e.to);
inq[e.to] = 1;
}
}
}
}
if(d[t]==inf) return false;
flow += a[t];
cost += (ll)a[t]*(ll)d[t];
int u = t;
while(u!=s){
edges[p[u]].flow += a[t];
edges[p[u]^1].flow -= a[t];
u = edges[p[u]].from;
}
return true;
}
ll Mincost(int s,int t,int & flow)
{
flow = 0;
ll cost = 0;
while(BellmanFord(s,t,flow,cost)) ;
return cost;
}
};
MCMF g;
int main()
{
while(scanf("%d %d",&n,&m)!=EOF){
int s , e ,length;
int source = 0 , sink = n + 1;
g.init(n+1);
for(int i=0;i<m;i++){
scanf("%d %d %d",&s,&e,&length);
g.AddEdge(s,e,1,length);
g.AddEdge(e,s,1,length);
}
g.AddEdge(source,1,2,0);
g.AddEdge(n,sink,2,0);
int flow;
ll ans1 = g.Mincost(source,sink,flow);
printf("%lld\n",ans1);
}
return 0;
}
0 0
- 【POJ2135】Farm Tour 最小费用最大流
- Poj2135 Farm Tour (最小费用流)
- Poj2135 Farm Tour 最小费用流
- poj2135 Farm Tour 最小费用最大流
- poj2135 Farm Tour(最小费用流)
- POJ2135 Farm Tour 【最小费用最大流】
- POJ2135 Farm Tour 最小费用流
- poj2135 Farm Tour -最小费用流
- POJ2135 Farm Tour 最小费用流
- POJ2135 Farm Tour(最小费用流)
- POJ2135 Farm Tour(最小费用最大流)
- POJ2135--Farm Tour(最小费用最大流)
- 【POJ2135】Farm Tour(最小费用最大流)
- POJ2135 Farm Tour 无向图最小费用流
- POJ2135-Farm Tour(固定流量的最小费用流)
- POJ2135 Farm Tour —— 最小费用最大流
- POJ2135 Farm Tour(最小费用最大流裸题)
- poj2135-费用流&费用流模板-Farm Tour
- Java基础——类成员
- Effective C++_Item5笔记
- 局部变量与全局变量
- 数据结构笔记--总结各种查找算法及其应用
- 数据结构笔记--实际软件开发中用到的最多的数据结构和算法
- POJ2135 Farm Tour 最小费用流
- 【Web容器】Tomcat源码分析(5)-请求原理分析(上)
- Linux-(C)IO多路复用之epoll学习(转载)
- 输入某年某月某日,判断这一天是这一年的第几天?
- Laravel安装记录
- XML解析之SAX解析
- 实例讲解虚拟机3种网络模式(桥接、nat、Host-only)
- nodejs使用request发送http请求
- javascript编程之OOP