傳送門:qaqqaq
因為要在最大流的情況下,保證最小費用,所以我們在增廣時就用spfa跑乙個最短路進行增廣,雖然這個路徑可能不在最大流中,但殘量網路可以保證我們這個「可以反悔的貪心」不會出錯~
具體寫法:spfa+ek
**:
#include#define mk make_pairview codeusing
namespace
std;
typedef pair
pii;
const
int inf=(int
)2e9;
const
int n=1020*50
;int
n,m,s,t;
int first[n*2],nxt[n*4],point[n*4],cost[n*4],flow[n*4],e=0
;void add(int x,int y,int z,int
c)void add_edge(int x,int y,int z,int
c)int
dis[n],inq[n],pre_point[n],f[n],pre_edge[n];
void
init_spfa()
queue
q;bool
spfa()}}
}return pre_point[t]!=-1;}
pii solve()
}return
mk(max_flow,min_cost);
}void
init()
}int
main()
再來一道題:
傳送門:qaqqaq
題意:有$n$個盒子(1<=$n$<=1000)圍成乙個圈,每個盒子有$a_$個球,所有盒子的球的總數小於等於$n$.每一次移動,可以把乙個球移動到它的乙個相鄰的盒子內.
現在要使得每個盒子的球數$<=1$,求最少的移動次數
思路:直接說建圖吧(網路流主要就是難在建圖)
我們造乙個源點,乙個匯點,源點和每乙個點連一條容量為$a_$,費用為$0$的邊,匯點和每乙個點連一條容量為$1$,費用為$0$的邊,對於中間的點,我們對於它和它左右兩點各連一條容量為$inf$,費用為$1$的邊。
這樣我們跑一遍最小費用最大流即可(即在總流量為$sumball$的情況下,費用最小)
**:
#include#define mk make_pairview codeusing
namespace
std;
typedef pair
pii;
const
int inf=(int
)2e9;
const
int n=100020;
intn,m,s,t;
int first[n*2],nxt[n*4],point[n*4],cost[n*4],flow[n*4],e=0
;void add(int x,int y,int z,int
c)void add_edge(int x,int y,int z,intc)
intdis[n],inq[n],pre_point[n],f[n],pre_edge[n];
void
init_spfa()
queue
q;bool
spfa()}}
}return pre_point[t]!=-1;}
intsolve()
}return
min_cost;}
inta[n];
void
init()}
intmain()
最小費用最大流模板
const int n 1010 點 const int m 2 10010 邊 const int inf 1000000000 struct nodee m int next1 m point n dis n q n pre n ne ne為已新增的邊數,next,point為鄰接表,dis為花...
最小費用最大流模板
一 最小費用最大流的模型 在保證流量最大的前提下,所需的費用最小,這就是最小費用最大流問題 帶有費用的網路流圖 g v,e,c,w v 頂點 e 弧 c 弧的容量 w 單位流量費用。任意的弧對應非負的容量c i,j 和單位流量費用w i,j 滿足 流量f是g的最大流。在f是g的最大流的前提下,流的費...
最小費用最大流 模板
因為含有負權邊,所以使用spfa進行增廣。指定流量的最小費用流可以初始化乙個f,然後每次一直迴圈到f 0為止。函式返回的是最大流,當然經過少量修改可以返回最小費用,利用最小流量乘以相應的費用即可。prevv記錄父節點,preve記錄當前節點對應父節點的第幾條邊。const int inf 0x3ff...