最大流(三)―― Dinic算法

匿名 (未验证) 提交于 2019-12-02 23:49:02

因为没打优化,比打了优化的SAP算法慢了很多,超时了。

#include<vector> #include<cstdio> #include<iostream> #include<cmath> #include<queue> #define numm ch-48 #define pd putchar(' ') #define pn putchar('\n') #define pb push_back #define fi first #define se second #define fre1 freopen("1.txt","r",stdin) #define fre2 freopen("2.txt","w",stdout) using namespace std; template <typename T> void read(T &res) {     bool flag=false;char ch;     while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true);     for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm);     flag&&(res=-res); } template <typename T> void write(T x) {     if(x<0) putchar('-'),x=-x;     if(x>9) write(x/10);     putchar(x%10+'0'); } const int maxm=8000010;     ///有反向边,边数要开两倍 const int maxn=1000010; const int inf=0x3f3f3f3f; const int INF=0x7fffffff; typedef long long ll; struct node {   ///链式前向星     ll c;     int to,net; }e[maxm]; int head[maxn],level[maxn],que[maxn]; int n,cnt=0; void init() { //    cnt=0; //    for(int i=1;i<=n;i++)   ///单测试用例可不用 //        level[i]=0;     for(int i=1;i<=n;i++)         head[i]=-1; } void add(int u,int v,ll c) {     e[cnt].to=v;     e[cnt].c=c;     e[cnt].net=head[u];     head[u]=cnt++; } bool bfs(int st,int ed) {     int iq=0;     for(int i=1;i<=n;i++)         level[i]=0;     level[st]=1;     que[iq++]=st;     for(int i=0;i<iq;i++) {         int top=que[i];         if(top == ed) return true;         for(int k=head[top];k!=-1;k=e[k].net)             if(!level[e[k].to]&&e[k].c) {                 que[iq++]=e[k].to;                 level[e[k].to]=level[top]+1;             }     }     return false; } ll dfs(int now,ll max_flows,int ed) {     if(now==ed) return max_flows;     ll res=0;     for(int k=head[now];k!=-1;k=e[k].net)         if(e[k].c&&level[e[k].to]==level[now]+1) {             ll f=dfs(e[k].to,min(max_flows-res,e[k].c),ed);             res+=f;             e[k].c-=f;             e[k^1].c+=f;             if(res == max_flows) return res;         }     return res; } ll Dinic(int st,int ed) {     ll max_flows=0;     while(bfs(st,ed)) max_flows+=dfs(st,INF,ed);     return max_flows; } int main() {     int st,m,ed;     read(n),read(m),read(st),read(ed);     init();     for(int i=1;i<=m;i++) {         int u,v;         ll c;         read(u),read(v),read(c);         add(u,v,c);         add(v,u,0);     ///建立反向边     }     write(Dinic(st,ed));pn;     return 0; } ///Dinic算法

  

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!