poj1273(网络流最大流 EK算法&&dinic算法)

来源:互联网 发布:什么是java分布式 编辑:程序博客网 时间:2024/05/20 09:27
#include<stdlib.h>#include<stdio.h>#include<string.h>#include<queue>using namespace std;#define N 210#define INF 0x7FFFFFFFint path[N],map[N][N],flow[N],start,end,ans;int n,m;queue<int> q;int dfs(){    int i,j,t;    while(!q.empty())q.pop();    for(i=1;i<=m;i++)    {        path[i]=-1;        flow[i]=0;    }    path[start]=0;flow[start]=INF;    q.push(start);       while(!q.empty())    {         t=q.front();         q.pop();         if(t==end)break;//??         for(i=1;i<=m;i++)         {             if(i!=start&&path[i]==-1&&map[t][i])             {                 flow[i]=min(flow[t],map[t][i]);                 q.push(i);                 path[i]=t;             }         }    }    if(path[end]==-1)return -1;    return flow[end];}void Edmond_Krpe(){     int now;     int pre;     int dis;     while((dis=dfs())!=-1)     {         now=end;         ans+=dis;         while(now!=start)         {             pre =path[now];             map[pre][now]-=dis;             map[now][pre]+=dis;             now=pre;         }     }}int main(){    int i,u,v,f;    while(scanf("%d%d",&n,&m)!=EOF)    {       ans=0;       memset(map,0,sizeof(map));       for(i=1;i<=n;i++)       {           scanf("%d%d%d",&u,&v,&f);           map[u][v]+=f;       }       start=1;end=m;       Edmond_Krpe();       printf("%d\n",ans);      }    return 0;}/*5 41 2 401 4 202 4 202 3 303 4 10*/

以上是EK算法实现

下面用dinic算法实现,其实差不离,就是将EK中的path记录的路径在Dinic中用DFS分层图的方法去找

#include<stdio.h>#include<stdlib.h>#include<queue>#include<string.h>using namespace std;#define N 205#define inf 0x7FFFFFFFint dis[N],map[N][N];int n,m;int start,end;queue<int> q;int min(int a,int b){return a<b?a:b;}void init(){     for(int i=1;i<=n;i++)         dis[i]=-1;     dis[start]=0;     while(!q.empty())q.pop();     q.push(start);}int bfs()//看是否能增广{    init();    int t;    while(!q.empty())    {        t=q.front();        q.pop();        for(int i=1;i<=m;i++)        {            if(dis[i]<0&&map[t][i]>0)            {               dis[i]=dis[t]+1;               q.push(i);            }        }    }    if(dis[end]>0)    return 1;    return 0;}int findDfs(int x,int low)//能增广就DFS找出路径{    int addflow;    if(x==end)return low;    for(int i=1;i<=m;i++)    {        if(map[x][i]>0        &&dis[i]==dis[x]+1//i是否为x的下一层,不是的话放弃        &&(addflow=findDfs(i,min(low,map[x][i]))))//总是寻找下一层的点并且联通的点,直到找到终点参考博客请点击           {              map[x][i]-=addflow;              map[i][x]+=addflow;              return addflow;//这个addflow一直是最小的可增广的路径           }    }    return 0;}int main(){    int i,u,v,dist,ans;    while(scanf("%d%d",&n,&m)!=EOF)    {       ans=0;start=1;end=m;       memset(map,0,sizeof(map));       for(i=1;i<=n;i++)       {          scanf("%d%d%d",&u,&v,&dist);          map[u][v]+=dist;       }       while(bfs())       {           ans+=findDfs(start,inf);       }       printf("%d\n",ans);    }    return 0;}


原创粉丝点击