标签:
按照有下界网络流求可行流的方法求出最小费用可行流。
写的费用流多路增广,比裸ek快一点。
其实这题有很优越的建图方法,然而并不会。
#include<bits/stdc++.h>
#define N 309
using namespace std;
int cost,n;
int d[N],s=N-1,t=N-2;
bool p[N];
const int inf=1061109567;
struct edge{
edge* s;
int v,w,cp;
}e[N*N],*back(e),*h[N];
void add(
int u,int v,int w,int cp){
h[u]=&(*back++
=(edge){h[u],v,w,cp});
h[v]=&(*back++
=(edge){h[v],u,-w,0});
}
bool spfa(){
static bool a[N];
queue<int> q;
q.push(s);
memset(d,63,sizeof d);
d[s]=0;
while(q.size()){
int u=q.front();
q.pop();
a[u]=0;
for(edge* i=h[u];i;i=i->s)
if(i->cp
&&d[i->v]>d[u]+i->w){
d[i->v]=d[u]+i->w;
if(!a[i->v]){
a[i->v]=1;
q.push(i->v);
}
}
}
return d[t]!=inf;
}
int dfs(int u,int a){
int s=0;
p[u]=1;
for(edge* i=h[u];s!=a
&&i;i=i->s){
if(!i->cp||p[i->v]
||d[i->v]!=d[u]+i->w)
continue;
int j=min(a-s,i->cp);
if(i->v==t
||(j=dfs(i->v,j))){
s+=j;
cost+=i->w*j;
i->cp-=j;
e[i-e^1].cp+=j;
}
}
return s;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
int j,v,w;
scanf("%d",&j);
add(i,t,0,j);
add(i,1,0,inf);
while(j--){
scanf("%d%d",&v,&w);
add(s,v,w,1);
add(i,v,w,inf);
}
}
while(spfa()){
memset(p,0,sizeof p);
dfs(s,inf);
}
printf("%d\n",cost);
}
标签:
原文地址:http://www.cnblogs.com/f321dd/p/5596196.html