zkw费用流

时间:2021-03-15 05:40:26

期末结束,竞赛生活继续开始,先怒刷完寒假作业再说

至于期末考试,数学跪惨,各种哦智障错,还有我初中常用的建系大法居然被自己抛至脑后,看来学的还是不扎实,以后数学要老老实实学。物理被永哥黑了两分,然后很庆幸自己计算题没错,化学又犯了看A选C的毛病,但就算这不算也考的很不理想,归结下来是因为做题速度太慢,需要在寒假练习速度与正确性(化学二卷正确率还是可以的,哈哈哈),英语因为没时间写作文,导致作文得了七分(哭死),而且智障课内完型还错了,原因是图卡时候速度太快,完型最后两题两个D写连起来了,导致填成了两个B。。。生物我已经知足了,但是智障与审题还是丢了分。这回比八班总班平高了6分,虽然感觉自己很虚,但面对成绩还是可以的,慢慢进步吧。

然后刚学了zkw费用流,这个与普通费用流算法的区别就在于spfa的时候是从汇点到源点做spfa,好像这样能剪一剪枝,排除从源点分出的一些无用的分叉,还有找增广路时是一次找一大坨,类似dinic,下面贴代码:

 #include<iostream>
 #include<algorithm>
 #include<cmath>
 #include<cstring>
 #include<queue>
 #include<cstdio>
 using namespace std;
 typedef long long LL;
 inline int read()
 {
     ,f=;char c=getchar();
     ;c=getchar();}
     +c-';c=getchar();}
     return x*f;
 }
 ;
 ;
 int first[maxn],n,m,vis[maxn],dis[maxn],a,b,c,d,ans;
 queue <int> Q;
 struct Edge
 {
     int u,v,f,w,next;
     Edge() {}
     Edge(int _1,int _2,int _3,int _4,int _5) : u(_1),v(_2),f(_3),w(_4),next(_5) {}
 }e[maxn];
 void addEdge(int i,int a,int b,int c,int d)
 {
     e[i]=Edge(a,b,c,d,first[a]);
     first[a]=i;
 }
 bool spfa()
 {
     memset(vis,,sizeof(vis));
     ;i<=n;i++)dis[i]=oo;
     while(Q.size())Q.pop();
     dis[n]=;vis[n]=;Q.push(n);
     while(Q.size())
     {
         int now=Q.front();Q.pop();
         ;i=e[i].next)
             ].f && dis[now]+e[i^].w<dis[e[i].v])
             {
                 dis[e[i].v]=dis[now]+e[i^].w;
                 if(!vis[e[i].v])
                 {
                     vis[e[i].v]=;
                     Q.push(e[i].v);
                 }
             }
         vis[now]=;
     }
     ]!=oo;
 }
 int dfs(int x,int flow)
 {
     vis[x]=;
     if(x==n)return flow;
     ;
     ;i=e[i].next)
         if(dis[e[i].v]==dis[x]-e[i].w && e[i].f && !vis[e[i].v])
         {
             now=flow-used;
             now=dfs(e[i].v,min(now,e[i].f));
             ans+=now*e[i].w;
             e[i].f-=now; e[i^].f+=now;
             used+=now;
             if(used==flow)return flow;
         }
     return used;
 }
 void zkw()
 {
     while(spfa())
     {
         vis[n]=;
         while(vis[n])
         {
             memset(vis,,sizeof(vis));
             dfs(,oo);
         }
     }
 }
 int main()
 {
     memset(first,-,sizeof(first));
     n=read();m=read();
     ;i<m;i++)
     {
         a=read();b=read();c=read();d=read();
         addEdge(*i,a,b,c,d);
         addEdge(*i+,b,a,,-d);
     }
     zkw();
     printf("%d",ans);
     ;
 }

明天就要冬令营了,加油啊!!