LOJ#101最大流

来源:互联网 发布:js怎么让div隐藏 编辑:程序博客网 时间:2024/06/07 10:25

本博客由于博主太弱可能已经废了你看博主多久没更新博客肯定是天天被吊打已经没有勇气写博客了

马上就要NOI了,NOI之前我们当然应该压压代码卡卡常准备NOI零爆爆底垫垫啦(雾)

事情是这样的

下午在家无聊睡觉的我突然从梦中醒来,贴了一个Dinic和fread的板子往上一交,发现根本就没有TLE嘛,可是AC时间却是rank1的十倍,果然不愧千古神犇wxh。

如图(越卡常越慢菜鸡瑟瑟发抖)

然后蒟蒻zzt滚出家门,到了晚上八点半才回家,造了一组随机数据,由于机子比较菜发现需要17s才能跑出来(-O2),然后蒟蒻zzt表示不服,于是就有了今天的被吊打故事。

先贴一个loj上总共跑了17s的代码吧QAQ

#include"bits/stdc++.h"using namespace std;typedef long long ll;namespace io{const int L=(1<<20)+1;char _buf[L],*S,*T,c;char gc(){if(S==T){T=(S=_buf)+fread(_buf,1,L,stdin);return S==T?EOF:*S++;}return*S++;}template<class T>void gi(T&x){for(c=gc();c<'0'||c>'9';c=gc());x=c&15;for(c=gc();c>='0'&&c<='9';c=gc())x=x*10+(c&15);}char obuf[L],*op=obuf,*end=obuf+(L-1);void writechar(char x){*op++=x;if(op==end)fwrite(obuf,1,L-1,stdout),op=obuf;}int tp;char st[25];template<class T>void print(T a){if(!a)writechar('0');else{for(tp=0;a;st[tp++]=a%10+'0',a/=10);for(tp--;~tp;writechar(st[tp--]));}}void cbuf(){fwrite(obuf,1,op-obuf,stdout),op=obuf;}};using io::gi;using io::writechar;using io::print;const int N=1000005,M=8000005,inf=0x7FFFFFFF;int h[N],nxt[M],to[M],flow[M],tmp=1,n,m,S,T,q[N],l,r,d[N];void addedge(int u,int v,int f){to[++tmp]=v, nxt[tmp]=h[u], h[u]=tmp, flow[tmp]=f;to[++tmp]=u, nxt[tmp]=h[v], h[v]=tmp, flow[tmp]=0;}bool bfs(){register int i;memset(d,-1,(n+1)<<2);for(d[q[l=r=1]=S]=1;l<=r;l++)for(i=h[q[l]];i;i=nxt[i])if(d[to[i]]==-1&&flow[i])d[to[i]]=d[q[l]]+1,q[++r]=to[i];return d[T]!=-1;}int dfs(int x,int mf){if(x==T)return mf;register int res=0,p,i;for(i=h[x];i;i=nxt[i])if(d[to[i]]==d[x]+1&&flow[i]){p=dfs(to[i],min(mf,flow[i]));flow[i]-=p,flow[i^1]+=p,res+=p,mf-=p;if(!mf)break;}if(!res)d[x]=-1; return res;}int main(){gi(n),gi(m),gi(S),gi(T);int u,v,c,i;for(i=1;i<=m;i++){gi(u),gi(v),gi(c);if(u==v||!c)continue;addedge(u,v,c);}ll ans=0;while(bfs())ans+=dfs(S,inf);print(ans);io::cbuf();return 0;}

想要变快似乎需要魔改? zzt表示瑟瑟发抖并准备开始优化。

-- 半个小时后zzt改了个vector版本发现更慢了

然后zzt写了一个每次存边的版本,发现要快很多,可是似乎还是比许多dalao慢得多。

#include"bits/stdc++.h"using namespace std;typedef long long ll;namespace io{const int L=(1<<20)+1;char _buf[L],*S,*T,c;char gc(){if(S==T){T=(S=_buf)+fread(_buf,1,L,stdin);return S==T?EOF:*S++;}return*S++;}template<class T>void gi(T&x){for(c=gc();c<'0'||c>'9';c=gc());x=c&15;for(c=gc();c>='0'&&c<='9';c=gc())x=x*10+(c&15);}char obuf[L],*op=obuf,*end=obuf+(L-1);void writechar(char x){*op++=x;if(op==end)fwrite(obuf,1,L-1,stdout),op=obuf;}int tp;char st[25];template<class T>void print(T a){if(!a)writechar('0');else{for(tp=0;a;st[tp++]=a%10+'0',a/=10);for(tp--;~tp;writechar(st[tp--]));}}void cbuf(){fwrite(obuf,1,op-obuf,stdout),op=obuf;}};using io::gi;using io::writechar;using io::print;const int N=1000005,M=8000005,inf=0x7FFFFFFF;int h[N],nxt[M],to[M],flow[M],tmp=1,n,m,S,T,q[N],l,r,d[N],pp;void addedge(int u,int v,int f){to[++tmp]=v, nxt[tmp]=h[u], h[u]=tmp, flow[tmp]=f;to[++tmp]=u, nxt[tmp]=h[v], h[v]=tmp, flow[tmp]=0;}struct e{int*flow, *revflow, v;e(){};e(int _v, int*fl, int*rfl){flow = fl, revflow = rfl, v = _v;}} edg[M>>1];int from[M>>1], ed[M>>1], total;bool bfs(){int i,u,v; total = 0;for(d[q[l=r=1]=S] = pp;l<=r;l++){u=q[l]; from[u]=total+1; pp++;for(i=h[u]; i; i=nxt[i]){v=to[i];if(!flow[i])continue;if(d[v]<pp) d[v]=d[u]+1, q[++r]=to[i];if(d[v]==d[u]+1) edg[++total] = e(v, flow+i, flow+(i^1));}ed[u]=total;}return d[T]>=pp;}int dfs(int x,int mf){if(x==T)return mf;register int res=0,p,i,v,*a,*b;for(i=from[x]; i<=ed[x]; i++){v=edg[i].v; a=edg[i].flow;if (!*a) {from[x]=i+1; continue;}p=dfs(v,min(mf,*a)); b=edg[i].revflow;*a-=p, *b+=p, res+=p, mf-=p;if(!mf) break;}if(!res) d[x]=-1; return res;}int main(){gi(n),gi(m),gi(S),gi(T);int u,v,c,i;for(i=1;i<=m;i++){gi(u),gi(v),gi(c);if(u==v||!c) continue;addedge(u,v,c);}ll ans=0;while(bfs())ans+=dfs(S,inf);print(ans);io::cbuf();return 0;}

看起来只有改连边方式才能拯救我可怜的代码了……

#include"bits/stdc++.h"using namespace std;typedef long long ll;namespace io{const int L=(1<<20)+1;char _buf[L],*S,*T,c;#define gc (S==T ? T=(S=_buf)+fread(_buf,1,L,stdin), *S++ : *S++)void gi(int&x){for(c=gc;c<'0'||c>'9';c=gc); x=c&15;for(c=gc;c>='0'&&c<='9';c=gc) x=x*10+(c&15);}char obuf[L],*op=obuf,*end=obuf+(L-1);void writechar(char x){*op++=x;if(op==end)fwrite(obuf,1,L-1,stdout),op=obuf;}int tp;char st[25];template<class T>void print(T a){if(!a)writechar('0');else{for(tp=0;a;st[tp++]=a%10+'0',a/=10);for(tp--;~tp;writechar(st[tp--]));}}void cbuf(){fwrite(obuf,1,op-obuf,stdout),op=obuf;}};using io::gi;using io::writechar;using io::print;const int N=1000005,M=8000005,inf=0x7FFFFFFF;int h[N],nxt[M],to[M],flow[M],tmp=1,n,m,S,T,q[N],l,r,d[N],pp=1;void addedge(int u,int v,int f){to[++tmp]=v, nxt[tmp]=h[u], h[u]=tmp, flow[tmp]=f;to[++tmp]=u, nxt[tmp]=h[v], h[v]=tmp, flow[tmp]=0;}int from[N], ed[N], A[M>>1], V[M>>1], total;bool bfs(){int i,j=pp,u,v; total = 0;for(d[q[l=r=1]=S] = pp;l<=r;l++){u=q[l]; from[u]=total+1; pp++;for(i=h[u]; i; i=nxt[i]){v=to[i];if(!flow[i])continue;if(d[v]<j) d[v]=d[u]+1, q[++r]=v;if(d[v]==d[u]+1) A[++total]=i, V[total]=v;}ed[u]=total;}return d[T]>=j;}int dfs(int x,int mf){if(x==T)return mf;register int p,i,v,a;for(i=from[x]; i<=ed[x]; i++){v=V[i], a=A[i];if (!flow[a]) {from[x]=i+1; continue;}p=dfs(v, min(mf,flow[a]));if (p) {flow[a]-=p, flow[a^1]+=p;return p;} else from[x] = i+1;if(!mf) break;}d[x] = -1;return 0;}int main(){gi(n),gi(m),gi(S),gi(T);int u,v,c,i;for(i=1;i<=m;i++){gi(u),gi(v),gi(c);if(u==v||!c) continue;addedge(u,v,c);}ll ans=0; int flow;while(bfs()) while(flow=dfs(S,inf)) ans+=flow;print(ans);io::cbuf();return 0;}

改了方式之后顺利跑上oj第一页

原创粉丝点击