明天省夏要講網絡流啦!晚上翻出自己的模板發現是藍書模板QwQ。。拿出以前的提交代碼(AC過的?)
曾經的提交記錄
在luogu上重新提交一遍,結果gg...OVO
沒有去除多余的inline
去除了多余的inline
論強數據練考驗模板的好處?
於是決定自造一份正常的模板。。。
主要的優化有三——
(1) 當前弧優化,防止因重復訪問一條邊造成效率降低。
(2) 記錄無法增廣的點。
(3) 玄學優化?在Dinic的bfs過程中找到一條可增廣的路徑就返回(由於bfs的低效?),此優化在luogu的數據中表現良好。
具體可以看注釋
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<vector> 5 using namespace std; 6 #define inf 0x3f3f3f3f 7 8 int read(){ 9 bool flag=0; 10 char ch; 11 int re=0; 12 while((ch=getchar())!='-'&&(ch<'0'||ch>'9')); 13 ch=='-'?flag=1:re=ch-'0'; 14 while((ch=getchar())>='0'&&ch<='9') re=re*10+ch-'0'; 15 return flag?-re:re; 16 } 17 18 struct edge{ 19 int to,nxt,cap; 20 edge(int to=0,int nxt=0,int cap=0): 21 to(to),nxt(nxt),cap(cap){} 22 }; 23 24 const int maxn=10005,maxm=100005; 25 26 int n,m,s,t,cnt=1; 27 int tou[maxn],head[maxn],q[maxn],d[maxn]; 28 edge edges[maxm<<1]; 29 30 //增加一條流量為c的正向邊和流量為0的反向邊 31 //利於記錄邊的流量狀態 32 inline void add_edge(int from,int to,int c){ 33 edges[++cnt]=edge(to,head[from],c); 34 head[from]=cnt; 35 edges[++cnt]=edge(from,head[to],0); 36 head[to]=cnt; 37 } 38 39 void init(){ 40 n=read(); m=read(); s=read(); t=read(); 41 for(int i=0,from,to,c;i<m;i++){ 42 from=read(); to=read(); c=read(); 43 add_edge(from,to,c); 44 } 45 } 46 47 //尋找增廣路 48 bool bfs(){ 49 memset(d,-1,(n+1)<<2); 50 d[t]=0; q[1]=t; 51 int hh=1,tt=2; 52 while(hh!=tt){ 53 int cur=q[hh++]; 54 for(int e=head[cur];e;e=edges[e].nxt){ 55 int curto=edges[e].to; 56 if(d[curto]==-1&&edges[e^1].cap){ 57 //printf("%d\n",curto); 58 d[curto]=d[cur]+1; 59 q[tt++]=curto; 60 //找到一條邊就返回,玄學優化? 61 if(curto==s) return 1; 62 } 63 } 64 } 65 //沒有玄學優化的寫法,有了玄學優化是不是該return 0? 66 return d[s]!=-1; 67 } 68 69 int dfs(int x,int f){ 70 if(f<=0) return 0; 71 if(x==t) return f; 72 int ca=0; 73 //神秘的當前弧優化 74 for(int& e=head[x];e;e=edges[e].nxt){ 75 int curto=edges[e].to; 76 //並不是之前的dfs()中找到的增廣路啊 77 if(d[curto]+1!=d[x]) continue; 78 //利用限制流量 79 int w=dfs(curto,(edges[e].cap<f-ca)?edges[e].cap:(f-ca)); 80 //直接對路的流量進行修改 81 edges[e].cap-=w; edges[e^1].cap+=w; ca+=w; 82 //已達到了限制流量 83 if(ca==f) break; 84 } 85 //已經gg的尋找 86 if(!ca) d[x]=-1; 87 return ca; 88 } 89 90 int dinic(){ 91 int ans=0; 92 //****當前弧優化的必要操作 93 memcpy(tou,head,(n+1)<<2); 94 while(bfs()){ 95 ans+=dfs(s,inf); 96 memcpy(head,tou,(n+1)<<2); 97 } 98 return ans; 99 } 100 101 int main(){ 102 //freopen("temp.in","r",stdin); 103 init(); 104 printf("%d\n",dinic()); 105 return 0; 106 }
親測表現良好。。。