最小费用最大流
link
也是一道模板题,和最大流是一个道理。我学的这种写法是Dinic的改进版,给每条边维护两个边权,一个是流量,一个是费用。每次对费用用SPFA跑一个最短路,然后就着这个最短路去跑一次Dinic。唯一需要注意的是反边。考虑到反边的本质是让某条旧路径放弃原有的那一段路不走了,所以费用应该会减少,建边时对应的费用边权赋值为费用的相反数即可。
#include
#include
#include
//#define zczc
using namespace std;
const int N=5010;
const int M=50010;
const int inf=1e9;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
inline int min(int s1,int s2){
return s1qu;
bool inq[N],vis[N];
int dis[N],q[N],l,r;
bool check(){
memset(dis,0x3f,sizeof(dis));
memset(inq,false,sizeof(inq));
memset(vis,false,sizeof(vis));
dis[s]=0;qu.push(s);
while(!qu.empty()){
int wh=qu.front();qu.pop();inq[wh]=false;
for(int i=head[wh],th;i;i=e[i].next){
if(e[i].v1<=0||dis[wh]+e[i].v2>=dis[th=e[i].t])continue;
dis[th]=dis[wh]+e[i].v2;if(!inq[th])inq[th]=true,qu.push(th);
}
}
return dis[t]