首页 > 代码库 > POJ2135 最小费用最大流模板题
POJ2135 最小费用最大流模板题
练练最小费用最大流
此外此题也是一经典图论题
题意:找出两条从s到t的不同的路径,距离最短。
要注意:这里是无向边,要变成两条有向边
#include <cstdio>#include <cstring>#define MAXN 1005#define MAXM 10005#define INF 0x3f3f3f3fstruct Edge{ int y,c,w,ne;//c容量 w费用}e[MAXM*4];int n,m,x,y,w;int s,t,Maxflow,Mincost;int all,be[MAXN];int q[MAXM*4],dis[MAXN],pre[MAXN];//pre存的是当前点的前边bool vis[MAXN];void add(int x, int y, int c, int cost){ e[all].y=y;e[all].c=c;e[all].w=cost; e[all].ne=be[x]; be[x]=all++; e[all].y=x;e[all].c=0;e[all].w=-cost;//反向边费用取负 e[all].ne=be[y]; be[y]=all++;}void init(){ all=0; memset(be,-1,sizeof(be));}bool spfa(int s, int t){ for(int i=0; i<MAXN; i++) { dis[i]=INF; vis[i]=0; pre[i]=-1; } dis[s]=0; vis[s]=1; int head=0,tail=0; q[++tail]=s; while(head<tail) { int u=q[++head]; vis[u]=0; for(int i=be[u]; i!=-1; i=e[i].ne) { int v=e[i].y; if(e[i].c>0 && dis[v]>dis[u]+e[i].w) { dis[v]=dis[u]+e[i].w; pre[v]=i; if(!vis[v]) { vis[v]=1; q[++tail]=v; } } } } if(pre[t]==-1) return 0; return 1;}void MincostMaxflow(int s, int t){ Maxflow=0; Mincost=0; while(spfa(s,t)) { int minc=INF; for(int i=pre[t]; i!=-1; i=pre[e[i^1].y]) if(minc>e[i].c) minc=e[i].c; for(int i=pre[t]; i!=-1; i=pre[e[i^1].y]) { e[i].c-=minc; e[i^1].c+=minc; Mincost+=e[i].w*minc; } Maxflow+=minc; }}int main(){ scanf("%d%d",&n,&m); init(); s=n+1; t=n+2; for(int i=0; i<m; i++) { scanf("%d%d%d",&x,&y,&w); add(x,y,1,w); add(y,x,1,w); } add(s,1,2,0); add(n,t,2,0); MincostMaxflow(s,t); printf("%d\n",Mincost); return 0;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。