vjudge传送门[here]


  题目大意:给一个有(3≤v≤1000)个点e(3≤e≤10000)条边的有向加权图,求1~v的两条不相交(除了起点和终点外没有公共点)的路径,使权值和最小。

  正解是吧2到v-1的每个点拆成两个点,中间连一条容量为1,费用为0的边,然后求1到v的流量为2的最小费用流就行了。

Code

 /**
* Uva
* Problem#1658
* Accepted
*/
#include<iostream>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<fstream>
#include<sstream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
typedef bool boolean;
#define INF 0xfffffff
#define smin(a, b) a = min(a, b)
#define smax(a, b) a = max(a, b)
template<typename T>
inline boolean readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-' && ~x);
if(x == -){
return false;
}
if(x == '-'){
x = getchar();
aFlag = -;
}
for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
ungetc(x, stdin);
u *= aFlag;
return true;
} ///map template starts
typedef class Edge{
public:
int end;
int next;
int cap;
int flow;
int cost;
Edge(const int end = , const int next = , const int cap = , const int flow = , const int cost = ):end(end), next(next), cap(cap), flow(flow), cost(cost){}
}Edge; typedef class MapManager{
public:
int ce;
int *h;
Edge *edge;
MapManager(){}
MapManager(int points, int limit):ce(){
h = new int[(const int)(points + )];
edge = new Edge[(const int)(limit + )];
memset(h, , sizeof(int) * (points + ));
}
inline void addEdge(int from, int end, int cap, int flow, int cost){
edge[++ce] = Edge(end, h[from], cap, flow, cost);
h[from] = ce;
}
inline void addDoubleEdge(int from, int end, int cap, int cost){
addEdge(from, end, cap, , cost);
addEdge(end, from, cap, cap, -cost);
}
Edge& operator [](int pos){
return edge[pos];
}
inline int reverse(int pos){
return (pos & ) ? (pos + ) : (pos - );
}
inline void clean(){
delete[] h;
delete[] edge;
ce = ;
}
}MapManager;
#define m_begin(g, i) (g).h[(i)]
/// map template ends int n, m;
MapManager g; inline boolean init(){
if(!readInteger(n)) return false;
readInteger(m);
g = MapManager(n * , m * + n * );
for(int i = , a, b, w; i <= m; i++){
readInteger(a);
readInteger(b);
readInteger(w);
g.addDoubleEdge(a + n, b, , w);
}
for(int i = ; i <= n; i++){ //拆点
g.addDoubleEdge(i, i + n, , );
}
return true;
} int* dis;
boolean* visited;
int* last;
int* laste;
int* mflow;
int cost;
int s, t;
queue<int> que;
int sizee; inline void spfa(){
memset(dis, 0x7f, sizeof(int) * (sizee));
memset(visited, false, sizeof(boolean) * (sizee));
que.push(s);
last[s] = ;
dis[s] = ;
laste[s] = ;
mflow[s] = INF;
visited[s] = true;
while(!que.empty()){
int e = que.front();
que.pop();
visited[e] = false;
for(int i = m_begin(g, e); i != ; i = g[i].next){
int &eu = g[i].end;
if(dis[e] + g[i].cost < dis[eu] && g[i].flow < g[i].cap){
dis[eu] = dis[e] + g[i].cost;
last[eu] = e;
laste[eu] = i;
mflow[eu] = min(g[i].cap - g[i].flow, mflow[e]);
if(!visited[eu] && eu != t){
que.push(eu);
visited[eu] = true;
}
}
}
}
for(int i = t; i != s; i = last[i]){
g[laste[i]].flow += mflow[t];
g[g.reverse(laste[i])].flow -= mflow[t];
cost += mflow[t] * g[laste[i]].cost;
}
} inline void minCostFlow(){
s = + n, t = n, sizee = * n + ;
dis = new int[(const int)(sizee)];
visited = new boolean[(const int)(sizee)];
last = new int[(const int)(sizee)];
laste = new int[(const int)(sizee)];
mflow = new int[(const int)(sizee)];
spfa();
spfa();
} inline void solve(){
cost = ;
minCostFlow();
printf("%d\n", cost);
g.clean();
} int main(){
while(init()){
solve();
}
return ;
}

uva 1658 Admiral - 费用流的更多相关文章

  1. uva 1658 Admiral (最小费最大流)

    uva 1658 Admiral 题目大意:在图中找出两条没有交集的线路,要求这两条线路的费用最小. 解题思路:还是拆点建图的问题. 首先每一个点都要拆成两个点.比如a点拆成a->a'.起点和终 ...

  2. UVa 1658 Admiral(最小费用最大流)

    拆点费用流 --------------------------------------------------------------------- #include<cstdio> # ...

  3. UVALive - 6266 Admiral 费用流

    UVALive - 6266 Admiral 题意:找两条完全不相交不重复的路使得权值和最小. 思路:比赛的时候时间都卡在D题了,没有仔细的想这题,其实还是很简单的,将每个点拆开,连一条容量为1,费用 ...

  4. UVa 1658 - Admiral(最小费用最大流 + 拆点)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  5. UVA - 1658 Admiral (最小费用最大流)

    最短路对应费用,路径数量对应流量.为限制点经过次数,拆点为边.跑一次流量为2的最小费用最大流. 最小费用最大流和最大流EK算法是十分相似的,只是把找增广路的部分换成了求费用的最短路. #include ...

  6. uva 1658 Admiral 【 最小费用最大流 】

    拆点,每个点拆成 i,i' 在i 和i‘之间连一条费用为0,容量为1的边,就可以保证每个点只经过一次 特殊的点,1和n之间,,,n和2*n之间连一条费用为0,容量为2的边,可以求出两条路径 #incl ...

  7. uva 1658(最小费用最大流)

    题意:一个带权有向图,求起点到终点的两条路径权值之和最小,且两条路径没有公共点(除起点,终点): 分析:拆点法,将u拆成u和u',u-u'容量为1,费用为0,这样就能保证每个点只用一次,起点s-s'容 ...

  8. UVA - 1658 Admiral

    3. C - Admiral 题意:给定v(3<=v<=1000)个节点,e(3<=e<=10000)条边的又向加权图,求1->v的两条不相交的路径,使得权和最小. 思路 ...

  9. UVA 1658 Admiral 海上将军(最小费用流,拆点)

    题意: 一个有v个点的有向图,要从点1到点v需要找两条路径,两路径不可经过同一个点(除了1和v点).求这两条路径的最小费用(保证有解). 分析: 难在建图,其他套模板. 此图给的是超级复杂图,两个点之 ...

随机推荐

  1. HDU - 5806 NanoApe Loves Sequence Ⅱ 想法题

    http://acm.hdu.edu.cn/showproblem.php?pid=5806 题意:给你一个n元素序列,求第k大的数大于等于m的子序列的个数. 题解:题目要求很奇怪,很多头绪但写不出, ...

  2. mongostat和mongotop对mongodb数据库运行状态进行监控

    --mongostat工具是mongdb自带的监控工具,可以用来监控mongodb当前状态下的运行情况: [root@slave2 ~]# /usr/local/mongodb341/bin/mong ...

  3. Rhino

    http://shrinksafe.dojotoolkit.org/ a JavaScript interpreter

  4. https-->http and http-->https bitransfer

    openssl s_client -connect myupload.mysite.net:443/cgi-bin/posupload.cgi -status -cert client.pem -ve ...

  5. 学习计划 mysql 整数类型后面的数字,是什么意思?

    Mysql中定义整数类型的数字,是指定这个字段的长度么? 比如 INT(10) 10代表10个字节么?还是只能存储10为长度的数字内容? 今天本来想学习下字符类型,一下子发现了这个,感觉好有趣. -- ...

  6. Python开发【数据结构】:字典内部剖析

    字典内部剖析 开篇先提出几个疑问: 所有的类型都可以做字典的键值吗? 字典的存储结构是如何实现的? 散列冲突时如何解决? 最近看了一些关于字典的文章,决定通过自己的理解把他们写下来:本章将详细阐述上面 ...

  7. Vue打开新页面的方法

    let routeData = this.$router.resolve({ name: "detail", query: {goodsId:'1111'} }); window. ...

  8. getParameter和getAttribute区别

    (1)HttpServletRequest类有setAttribute()方法,而没有setParameter()方法 (2)当两个Web组件之间为链接关系时,被链接的组件通过getParameter ...

  9. 10 ref 和 out 之间的差别

    (1) 两者都是按地址传递的,使用后都将改变原来的数值 (2) ref传进去的參数必须在调用前初始化,out不必 (3) ref传进去的參数在函数内部能够直接使用,而out不可 (4) ref传进去的 ...

  10. [py]flask从0到1-模板/增删改查

    flask知识点 1.后端渲染html到前端 render_template 2.后端获取前端数据 request.args.get 3.前端获取后端数据 模板 4.警示消息 flash {{ get ...