題目大概意思是,有n個城市m條邊,要從1城市到n城市運送k的物品,求最少花費,每個邊有乙個係數ai花費的錢是ai*這條邊上運送物資數的平方,比如在係數為3的邊上運送了2的物品,則需要3*2*2的花費;
思路:由於每條邊的容量不超過5,所以可以把每一條邊拆成容量條流量為1的邊,他們的花費分別為1*ai,3*ai,5*ai,7*ai,9*ai;
花費依次遞增,然後每次找的最短路都是最小的,前幾次的加起來就是總的花費;比如前兩次的加起來就是4*ai,又因為每一條邊容量為1,則前兩次的總花費為ai*2*2也就是4*ai;
源點向1建容量為k花費0,n向匯點建容量為1花費為0,根據這個建圖,跑最大流最小費用即可,如果最大流不是k則輸出-1;
#include//每次找費用的最短路,更新殘留網路圖直到找不到最短路為止
#include//最大費用 權值取負值 結果取負值
#include
#include
#include
using
namespace
std;
const
int inf=0x3f3f3f3f;
struct node
node[1001000];
int head[1001000],cont,sumflow;
int vis[101000],dist[101000];
int pre[101000];
void init()
void add(int u,int v,int w,int cost)//建圖
// }
node[cont].u=u,node[cont].v=v;
node[cont].w=w,node[cont].cost=cost;
node[cont].next=head[u],head[u]=cont++;
node[cont].u=v,node[cont].v=u;
node[cont].w=0,node[cont].cost=-cost;//反向邊費用為負的
node[cont].next=head[v],head[v]=cont++;
}int spfa(int st,int ed)//尋找最短路
dist[st]=0;
vis[st]=1;
q.push(st);
while(!q.empty())}}
}if(dist[ed]==inf) return
0;//找不到最短路
return1;}
int mcmf(int st,int ed)
mincost+=dist[ed];//每次找到最短路後更新最小費用
flow+=1;//更新最大流
}sumflow=flow;//最大流
return mincost;
}int main()
}add(n,ed,k,0);
int ans=mcmf(st,ed);//最小費用最大流
if(sumflow!=k)
printf("-1\n");
else
printf("%d\n",ans);
}return
0;}
題目鏈結請戳這裡 hdu 3667(拆邊 最小費用最大流)
思路 由於花費的計算方法是a x x,因此必須拆邊,使得最小費用流模板可用,即變成a x的形式。具體的拆邊方法為 第i次取這條路時費用為 2 i 1 a i 5 每條邊的容量為1。如果這條邊通過的流量為x,那正好sigma 2 i 1 1 1 include2 include3 include4 i...
最小費用最大流模板(存邊)
函式功能介紹 addedge from,to,w,res 新增一條 x y,費用為w,殘量為res的邊,並一起新增其反向邊,由於從0號開始,相鄰兩個數代表的邊互為反向邊 即i號邊的反向邊是 i 1 spfa.init n 初始化點數n spfa.find s,t 在 源點為s,匯點為t的圖中尋找最小...
最小費用最大流
網 絡流的基本問題為 設乙個有向賦權圖g v,e v 其中有兩個特殊的節點s和s s稱為發點,s 稱為收點。圖中各 邊的方向和權數表示允許的流向和最大可能的流量 容量 問在這個網路圖中從發點流出到收點匯集,最大可通過的實際流量為多少?流向的分布情況為怎樣?設有乙個網路圖g v,e v e中的每條邊 ...