网络流之标号法

来源:互联网 发布:lrc歌词软件 编辑:程序博客网 时间:2024/05/01 03:44

时隔一个月,杂事也都差不多解决好了,新的学期新的开始。这是我初步学习网络流,为增广路问题做一个小的总结,以后有更好的模板再修改。

6 10 //顶点个数和弧数
0 1 8 2 //弧的起点,终点,容量,流量
0 2 4 3
1 3 2 2
1 4 2 2
2 1 4 2
2 3 1 1
2 4 4 0
3 4 6 0
3 5 9 3
4 5 7 2

求最大流流量

#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>#define MAXN 1000 //顶点个数最大值#define INF 1000000  //无穷大#define MIN(a,b) ((a)<(b)?(a):(b))struct ArcType{    int c,f;//容量,流量};ArcType Edge[MAXN][MAXN];int n,m;    //顶点个数和弧数int flag[MAXN]; //顶点的状态,三种int pre[MAXN]; //标号的第一个分量int alp[MAXN];  //标号的第二个分量,可改进两int queue[MAXN];    //BFS,模拟队列int v;  //队头元素int qs,qe;  //对列头位置,队列尾位置int i,j;    //循环变量void ford(){    while(1)    {        memset(flag,0xff,sizeof(flag));        memset(pre,0xff,sizeof(pre));        memset(alp,0xff,sizeof(alp));        flag[0]=0;pre[0]=0;alp[0]=INF;        qs=qe=0;        queue[qe]=0;        qe++;        while(qs<qe && flag[n-1]==-1)//汇点未标号        {            v=queue[qs];qs++;            for(i=0;i<n;i++)            {                if(flag[i]==-1)                {                    if(Edge[v][i].c<INF && Edge[v][i].f < Edge[v][i].c)//正向                    {                        flag[i]=0;pre[i]=v;                        alp[i]=MIN(alp[v],Edge[v][i].c-Edge[v][i].f);                        queue[qe]=i; qe++;                    }                    else if(Edge[i][v].c<INF && Edge[i][v].f>0)//反向                    {                        flag[i]=0;pre[i]=-v;                        alp[i]=MIN(alp[v],Edge[i][v].f);                        queue[qe]=i;    qe++;                    }                }            }            flag[v]=1;        }        if(flag[n-1]==-1 || alp[n-1]==0)            break;        int k1=n-1,k2=abs(pre[k1]);        int a=alp[n-1];//可改进量        while(1)        {            if(Edge[k2][k1].f<INF)//正向                Edge[k2][k1].f=Edge[k2][k1].f+a;            else//反向                Edge[k1][k2].f=Edge[k1][k2].f-a;            if(k2==0)//到了源点                break;            k1=k2;k2=abs(pre[k2]);        }    }//end of while    int maxFlow=0;    for(i=0;i<n;i++)    {        for(j=0;j<n;j++)        {            if(i==0 && Edge[i][j].f<INF)                maxFlow+=Edge[i][j].f;            if(Edge[i][j].f<INF)                printf("%d->%d:%d\n",i,j,Edge[i][j].f);        }    }    printf("%maxFlow:%d\n",maxFlow);}int main(){    int u,v,c,f;    //弧的起点,终点,容量,流量    scanf("%d%d",&n,&m);    for(i=0;i<n;i++)    {        for(j=0;j<n;j++)            Edge[i][j].c=Edge[i][j].f=INF;    }    for(i=0;i<m;i++)    {        scanf("%d%d%d%d",&u,&v,&c,&f);        Edge[u][v].c=c; Edge[u][v].f=f;    }    ford();}


0 0
原创粉丝点击