zoukankan      html  css  js  c++  java
  • POJ 1273 Drainage Ditches 最大流

    这道题用dinic会超时 用E_K就没问题 注意输入数据有重边。 POJ1273

    dinic的复杂度为O(N*N*M)E_K的复杂度为O(N*M*M)对于这道题,复杂度是相同的。

    然而dinic主要依靠Dfs寻找增广路,故而使用了太多次递归,而利用bfs寻找增广路(使用队列而不用递归)的EK等于用栈的方式实现了dinic的递归,所以 大幅提高了效率。

    最大流算法的核心就是找到增广路并且增加反向边流量,理解了这个,最大流算法就很简单了。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<queue>
    using namespace std;
    
    const  int maxn=200*2,s=1,INF=1e+8;
    
     int t,n,m,cap[maxn][maxn],from[maxn],to[maxn],c[maxn],f[maxn],dep[maxn],cur[maxn];
    vector<int>po[maxn];
    
    bool bfs()
    {
     bool vis[maxn];
     memset(vis,0,sizeof(vis));
     vis[s]=true;
     queue<int>q;
     q.push(s);
     dep[s]=0;
     while(!q.empty())
     	{
     	 int np=q.front();q.pop();
     	 if(np==t)return true;
     	 for(int i=0;i<po[np].size();i++)
     	 	{
     	 	 int ne=po[np][i];
     	 	 int next=to[ne];
     	 	 if((vis[next])||(c[ne]<=f[ne]))continue;
     	 	 vis[next]=true;
     	 	 dep[next]=dep[np]+1;
     	 	 q.push(next);
    		}
    	}
     return vis[t];
    }
     int min( int a, int b)
    {
     if(a<b)return a;
     	else return b;
    }
     int dfs(int now, int flo)
    {
      if(now==t||flo==0)return flo;
     int flow=0;
      for(int i=cur[now];i<po[now].size();i++)
      	{
      	 int ne=po[now][i];
      	 int next=to[ne];
      	 if(dep[next]!=dep[now]+1)continue;
      	 if(c[ne]<=f[ne])continue;
      	 long long int fd=dfs(next,min(flo,c[ne]-f[ne]));
      	 f[ne]+=fd;
      	 if(ne>=200)f[ne-200]-=fd;
      	 	else f[ne+200]-=fd;
      	 flow+=fd;
      	 flo-=fd;
      	 if(flo==0)break;
      	 cur[now]++;
    	}
     return flow;
    } 
     int d[maxn],fa[maxn];
    void find()
    {
     memset(d,0,sizeof(d));
     d[s]=INF;
     queue<int>q;
     q.push(s);
     while(!q.empty())
     	{
     	 int u=q.front();
     	 
     	 q.pop();
     	 for(int i=0;i<po[u].size();i++)
     	 	{
     	 	 int ne=po[u][i];
     	 	 int next=to[ne];
     	 	 if(d[next]!=0||cap[u][next]<=0)continue;
     	 	 d[next]=min(d[u],cap[u][next]);
     	 	 q.push(next);
     	 	 
     	 	 fa[next]=u;
     	 	 if(next==t)
     	 	 	{
     	 	 	 while(!q.empty())q.pop();
     	 	 	 return ;
    			}
    		}
    	}
    }
    int E_K()
    {
     int ans=0;
     while(true)
     	{
     	 find();
     	 ans+=d[t];
     	 if(d[t]==0)break;
     	 for(int i=t;i!=s;i=fa[i])
     	 	{
     	 	 cap[fa[i]][i]-=d[t];
     	 	 cap[i][fa[i]]+=d[t];
    		}
    	}
     return ans;
    }
    int main()
    {freopen("t.txt","r",stdin);
     ios::sync_with_stdio(false);
     while(cin>>n>>m)
     {
     
     t=m;
     memset(f,0,sizeof(f));memset(c,0,sizeof(c));memset(cap,0,sizeof(cap));
     for(int i=0;i<n;i++)
     	{
     	 cin>>from[i]>>to[i]>>c[i];po[from[i]].push_back(i);cap[from[i]][to[i]]+=c[i];//原边 
     	 from[i+200]=to[i];to[i+200]=from[i];po[to[i]].push_back(i+200);//反向边 
     	}
     cout<<E_K()<<endl;
    }
     return 0;
    }
    

      

  • 相关阅读:
    [转载]如何让企业网站发挥出应用的功能?
    [转载]创业流程
    velocity foreach跳出循环
    【转】cgi技术
    webx3 日志系统级别问题
    ibatis主键自增用法
    【转】java内部类总结
    java初始化顺序
    一点一点学习Ubuntu
    jboss 的端口修改
  • 原文地址:https://www.cnblogs.com/heisenberg-/p/6417454.html
Copyright © 2011-2022 走看看