UVa1658 Admiral
来源:互联网 发布:上海纽约大学 知乎 编辑:程序博客网 时间:2024/05/01 04:07
题目大意:给出一个v个点e条边的有向加权图,求1到v的两条不相交的(除了起点和终点没有公共点)的路径使边权之和最小。
我有话说:
用拆点法,把一个点分成两个点,中间连一条边,边的容量为1,费用为0,然后求1到v的流量为2的最小费用流即可。
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <vector>#include <cassert>#include <queue>using namespace std;const int maxn=2000+10;const int INF=1000000000;struct Edge{ int from,to,cap,flow,cost; Edge(int u,int v,int c,int f,int w):from(u),to(v),cap(c),flow(f),cost(w){}};struct MCMF{ int n,m; vector<Edge>edges; vector<int>G[maxn]; int inq[maxn]; int d[maxn]; int p[maxn]; int a[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){ edges.push_back(Edge(from,to,cap,0,cost)); edges.push_back(Edge(to,from,0,0,-cost)); m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BellmanFord(int s,int t,int flow_limit,int& flow,int& cost){ for(int i=0;i<n;i++)d[i]=INF; memset(inq,0,sizeof(inq)); d[s]=0;inq[s]=1;p[s]=0;a[s]=INF; queue<int>Q; Q.push(s); while(!Q.empty()){ int u=Q.front();Q.pop(); inq[u]=0; for(int i=0;i<G[u].size();i++){ Edge& e=edges[G[u][i]]; if(e.cap>e.flow&&d[e.to]>d[u]+e.cost){ d[e.to]=d[u]+e.cost; p[e.to]=G[u][i]; a[e.to]=min(a[u],e.cap-e.flow); if(!inq[e.to]){Q.push(e.to);inq[e.to]=1;} } } } if(d[t]==INF)return false;//无法增广 if(flow+a[t]>flow_limit)a[t]=flow_limit-flow; flow+=a[t]; cost+=d[t]*a[t]; for(int u=t;u!=s;u=edges[p[u]].from){ edges[p[u]].flow+=a[t]; edges[p[u]^1].flow-=a[t]; } return true; } int MincostFlow(int s,int t,int flow_limit,int& cost){ int flow=0;cost=0; while(flow<flow_limit&&BellmanFord(s,t,flow_limit,flow,cost)); return flow; }};MCMF g;int main(){ int n,m,a,b,c; while(scanf("%d%d",&n,&m)==2&&n){ g.init(n*2-2); for(int i=2;i<=n-1;i++)g.AddEdge(i-1,i+n-2,1,0);//每个点拆成两个点分编号为i-1和i+n-2(其实是i和i+n-1) while(m--){ scanf("%d%d%d",&a,&b,&c); if(a!=1&&a!=n)a+=n-2;else a--; b--; g.AddEdge(a,b,1,c); } int cost; g.MincostFlow(0,n-1,2,cost); printf("%d\n",cost); } return 0;}
0 0
- UVa1658 Admiral
- UVa1658: Admiral 题解
- uva1658 Admiral 最小费用最大流
- UVa1658 Admiral(拆点法+最小费用流)
- 最小费用最大流--uva1658 Admiral
- UVA1658 - Admiral(最小费用最大流+拆点)
- uva1658
- UVA1658
- Admiral UVA
- Admiral HDU
- Admiral UVA
- 最小费用流-uva1658
- uva1658 最小费用最大流
- [最小费用最大流]UVa1658
- LA6266 Admiral 费用流
- UVa 1658 Admiral
- uva 1658 Admiral
- HDU 6171 Admiral
- “赢在中国·蓝天碧水间”暴露的11位企业家的出身与人性
- C++实现基于单线程单客户模型的echo程序
- A*搜索算法
- 13、C语言和设计模式(命令模式)
- 中国天气客户端
- UVa1658 Admiral
- 20150808训练题+解题报告
- C语言数组与指针(重要)
- 当下的力量 读书笔记
- scala实现设计模式之原型模式
- iOS Core Animation详解(五)CATransition
- [学习笔记]JavaScript基础--任意值运动框架
- Linux 进程的前后台运行处理方法
- The mook jong(找规律+组合数学“隔板”思想)