1. 程式人生 > >#網路流,費用流,SLF優化,SPFA,zkw費用流#jzoj 1586 codevs 1362 洛谷 2604 網路擴容

#網路流,費用流,SLF優化,SPFA,zkw費用流#jzoj 1586 codevs 1362 洛谷 2604 網路擴容

題目

有兩個問題,首先求1到nn的最大流(不解釋了),然後求1到n使最大流擴充套件kk的費用,每擴充套件一個最大流,擴充套件一次邊的費用

分析

當然如何做第二個問題,可以重新建一個匯點流量是最大流+k+k,費用為0,並且原來的邊再建一次從uuvv,費用為該邊的費用,流量無限跑一次最大流,then就講完了

程式碼

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #define rr register
    using namespace std;
    struct
node{int y,w,f,next;}e[20005]; int n,k=1,dis[1003],ls[1003],ans; bool v[1003]; inline int in(){ rr int ans=0; rr char c=getchar(); while (c<48||c>57) c=getchar(); while (c>47&&c<58) ans=(ans<<3)+(ans<<1)+c-48,c=getchar(); return ans; } inline
void add(int x,int y,int w,int f){ e[++k]=(node){y,w,f,ls[x]}; ls[x]=k; e[++k]=(node){x,0,-f,ls[y]}; ls[y]=k; } inline int spfa(){//反向跑spfa memset(v,0,sizeof(v)); memset(dis,127/3,sizeof(dis)); dis[n]=0; v[n]=1; rr deque<int>q; q.push_back(n); while (q.size()){ rr int
x=q.front(); q.pop_front(); for (rr int i=ls[x];i;i=e[i].next) if (e[i^1].w&&dis[e[i].y]>dis[x]-e[i].f){ dis[e[i].y]=dis[x]-e[i].f; if (!v[e[i].y]){ v[e[i].y]=1; if (q.size()&&dis[e[i].y]<dis[q.front()]) q.push_front(e[i].y); else q.push_back(e[i].y); } } v[x]=0; } return dis[n+1]<707406378; } inline int dfs(int x,int now){//長得很像dinic if (x==n) {v[n]=1; return now;} rr int rest=0,f; v[x]=1; for (rr int i=ls[x];i;i=e[i].next) if (!v[e[i].y]&&e[i].w>0&&dis[e[i].y]+e[i].f==dis[x]){ rest+=(f=dfs(e[i].y,min(e[i].w,now-rest))); if (f) ans+=e[i].f*f,e[i].w-=f,e[i^1].w+=f; if (now==rest) return now; } return rest; } inline int zkw(){ int ans=0; while (spfa()){ do{ memset(v,0,sizeof(v)); ans+=dfs(n+1,1e9); }while (v[n]); } return ans; } int main(){ n=in(); rr int m=in(),t=in(); rr int w[m+1],f[m+1],t1; for (rr int i=1;i<=m;i++){ rr int x=in(),y=in(); w[i]=in(); f[i]=in(); add(x,y,w[i],0); } add(n+1,1,2333333,0); printf("%d ",t1=zkw()); t+=t1; e[k].w=0; e[k^1].w=t;//超級源點 for (rr int i=1;i<=m;i++) e[i<<1].w=w[i],e[i<<1|1].w=0;//重新建圖 for (rr int i=1;i<=m;i++) add(e[i<<1|1].y,e[i<<1].y,23333333,f[i]);//無限流量 zkw(); return !printf("%d",ans); }