最大流算法_最短增广算法

来源:互联网 发布:离婚原因数据统计 编辑:程序博客网 时间:2024/06/08 10:40
/*网络流最短增广路算法*/#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<cmath>#define oo 0x3f3f3f3fusing namespace std;const int maxn = 1010;struct node{    int c,f;};int n,m;node mp[maxn][maxn];int level[maxn];int last[maxn][maxn];int que[maxn*1000],qs,qe;int vis[maxn], par[maxn],add[maxn];void BuildRemain(int s, int t)//构造剩余网络{    memset(level, -1, sizeof(level));    memset(last, oo, sizeof(last));    for(int i = 1; i<= n; i++)    {        for(int j = 1; j <= n; j++)        {            if(mp[i][j].c!=oo)            {                if(mp[i][j].c-mp[i][j].f>0)                    last[i][j] = mp[i][j].c-mp[i][j].f;                if(mp[i][j].f>0)                last[j][i] = mp[i][j].f;            }        }    }    qs = qe = 0;    que[qs++] = s;    level[s] = 0;    while(qe<qs)//标号分层是对残余网络    {        int u = que[qe++];        for(int i = 1; i <= n; i++)        {            if(level[i]==-1&&last[u][i]!=oo)            {                level[i] = level[u]+1;                que[qs++] = i;            }        }    }}int FindBfs(int s, int t){    memset(vis, 0,sizeof(vis));    memset(par, 0,sizeof(par));    memset(add, 0,sizeof(add));    vis[s] = 1;    par[s] = 0;    add[s] = oo;    qs = qe = 0;    que[qs++] = s;    while(qe<qs&&!vis[t])    {        int u = que[qe++];        for(int i = 1; i <= n; i++)        {            if(!vis[i]&&last[u][i]!=oo&&level[i]==level[u]+1)            {                vis[i] = 1;                par[i] = u;                add[i] = min(add[u], last[u][i]);                que[qs++] = i;            }        }    }    if(!vis[t]||add[t]==0)return 0;    return 1;}void Zdzgl(int s,int t){    int flag = 0;    while(1)    {        /*(1)构造残留网络*/        BuildRemain(s,t);        /*(2)构造层次网络,寻找增广路*/        flag = 0;        while(FindBfs(s,t))        {            flag = 1;            int u = par[t],v=t;            int a = add[t];            while(u!=0)            {                if(mp[u][v].c!=oo)                    mp[u][v].f += a;                else                    mp[v][u].f -= a;                last[u][v]-=a;                if(last[u][v]==0)last[u][v] = oo;                v = u;                u = par[v];            }        }        if(!flag)break;    }    int Maxflow = 0;    for(int i = 1; i <= n; i++)    {        for(int j = 1; j <= n; j++)        {            if(i == 1 && mp[i][j].f!=oo)                Maxflow += mp[i][j].f;            if(mp[i][j].f != oo)                printf("%d-->%d: %d\n",i,j,mp[i][j].f);        }    }    printf("MaxFlow:%d\n",Maxflow);}int main(){    int u,v,c,f;    while(scanf("%d%d",&n,&m)!=EOF)    {        for(int i = 1; i <= n; i++)        {            for(int j = 1; j <= n; j++)            {                mp[i][j].c = mp[i][j].f = oo;            }        }        for(int i = 0; i < m; i++)        {            scanf("%d%d%d%d",&u,&v,&c,&f);            mp[u][v].c = c;            mp[u][v].f = f;        }        Zdzgl(1,n);    }    return 0;}/*7  121 2 4 31 3 10 32 3 1 12 5 7 22 4 2 03 4 5 13 6 3 34 5 6 04 6 1 15 7 9 26 5 5 06 7 6 4*/
0 0
原创粉丝点击