#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
//图节点
typedef struct VertexNode
{
char name;
int h;
int e;
}Vertex,*pVertex;
//图
typedef struct
{
int vn;
int **E; //容量C作为边矩阵的值
pVertex *V;
int **f; //流值
int **rE; // 残留边
}Graph,*pGraph;
//根据算法导论 图26-6初始化图
pGraph initGraph()
{
pGraph g=(pGraph)malloc(sizeof(Graph));
g->vn=6;
pVertex vs=(pVertex)malloc(sizeof(Vertex));
vs->name='s';
pVertex v1=(pVertex)malloc(sizeof(Vertex));
v1->name='1';
pVertex v2=(pVertex)malloc(sizeof(Vertex));
v2->name='2';
pVertex v3=(pVertex)malloc(sizeof(Vertex));
v3->name='3';
pVertex v4=(pVertex)malloc(sizeof(Vertex));
v4->name='4';
pVertex vt=(pVertex)malloc(sizeof(Vertex));
vt->name='t';
g->V=(pVertex*)malloc(g->vn*sizeof(pVertex));
g->V[0]=vs;
g->V[1]=v1;
g->V[2]=v2;
g->V[3]=v3;
g->V[4]=v4;
g->V[5]=vt;
g->E = (int**)malloc(g->vn*sizeof(int*));
g->f= (int**)malloc(g->vn*sizeof(int*));
g->rE= (int**)malloc(g->vn*sizeof(int*));
for(int i=0;i<g->vn;i++)
{
g->E[i]=(int*)malloc(g->vn*sizeof(int));
g->f[i]=(int*)malloc(g->vn*sizeof(int));
g->rE[i]=(int*)malloc(g->vn*sizeof(int));
}
for(int i=0;i<g->vn;i++)
{
for(int j=0;j<g->vn;j++)
{
g->E[i][j]=0;
//g->f[i][j]=0;
}
}
g->E[0][1]=16;
g->E[0][2]=13;
g->E[1][3]=12;
g->E[2][1]=4;
g->E[2][4]=14;
g->E[3][2]=9;
g->E[3][5]=20;
g->E[4][3]=7;
g->E[4][5]=4;
return g;
}
void initResidualNetwork(pGraph g)
{
for(int i=0;i<g->vn;i++)
{
for(int j=0;j<g->vn;j++)
{
g->rE[i][j]=0;
}
}
for(int i=0;i<g->vn;i++)
{
for(int j=0;j<g->vn;j++)
{
if(g->E[i][j]>0)
{
int x=g->E[i][j]-g->f[i][j];
if(x>0)
g->rE[i][j]=x;
if(g->f[i][j]>0)
g->rE[j][i]=g->f[i][j];
}
}
}
}
void initializePreflow(pGraph g,int s)
{
for(int i=0;i<g->vn;i++)
{
g->V[i]->e=g->V[i]->h=0;
}
for(int i=0;i<g->vn;i++)
{
for(int j=0;j<g->vn;j++)
{
g->f[i][j]=0;
}
}
g->V[s]->h=g->vn;
for(int i=0;i<g->vn;i++)
{
if(i != s)
{
g->f[s][i]=g->E[s][i];
g->V[i]->e=g->E[s][i];
g->V[s]->e -= g->E[s][i];
}
}
}
void push(pGraph g,int u,int v)
{
if(g->V[u]->e<=0)
return;
if(g->V[u]->h != g->V[v]->h+1)
return;
if(g->rE[u][v]<=0)
return;
int d=g->V[u]->e < g->rE[u][v] ? g->V[u]->e : g->rE[u][v];
//更新流
if(g->E[u][v]>0)
{
g->f[u][v]+=d;
}
else
{
g->f[v][u]-=d;
}
//更新超额流
g->V[u]->e-=d;
g->V[v]->e+=d;
//更新残存图
if(g->E[u][v]>0)
{
int x=g->E[u][v]-g->f[u][v];
g->rE[u][v]=x;
if(g->f[u][v]>0)
g->rE[v][u]=g->f[u][v];
}
}
//进入函数时,默认保证g->V[u]->e>0
//返回能从u进行push的邻接顶点位置
//返回-1代表残留图中该顶点无邻接点
int relabel(pGraph g,int u)
{
int minh=INT_MAX,minPos;
for(int i=0;i<g->vn;i++)
{
if(i==u)
continue;
if(g->rE[u][i]>0)
{
if(g->V[i]->h<g->V[u]->h)
return i;
else
{
if(g->V[i]->h<minh)
{
minh=g->V[i]->h;
minPos=i;
}
}
}
}
if(minh<INT_MAX)
{
g->V[u]->h=minh+1;
return minPos;
}
else//u没有邻接点时走到这里
return -1;
}
void printFlow2(pGraph g)
{
for(int i=0;i<g->vn;i++)
{
for(int j=0;j<g->vn;j++)
{
if(g->E[i][j]>0)
printf("(%c,%d,%d)->(%c,%d,%d) (%d/%d)\n",
g->V[i]->name,g->V[i]->h,g->V[i]->e,g->V[j]->name,g->V[j]->h,
g->V[j]->e,g->f[i][j],g->E[i][j]);
}
}
printf("\n");
for(int i=0;i<g->vn;i++)
{
for(int j=0;j<g->vn;j++)
{
if(g->rE[i][j]>0)
printf("%c->%c %d\n",g->V[i]->name,g->V[j]->name,g->rE[i][j]);
}
}
}
bool moreOperation(pGraph g,int s,int t)
{
int x=-1;
for(int i=0;i<g->vn;i++)
{
if(i==s || i==t)
continue;
if(g->V[i]->e<=0)
continue;
//push之前,保证g->V[i]->e>0
x=relabel(g,i);
if(x>=0)
{
push(g,i,x);
return true;
}
}
return false;
}
void genericPushRelabel(pGraph g,int s,int t)
{
initializePreflow(g,s);
initResidualNetwork(g);
int v=(s+1)%g->vn;
while(moreOperation(g,s,t))
{
//printFlow2(g);
};
}
void printFlow(pGraph g)
{
for(int i=0;i<g->vn;i++)
{
for(int j=0;j<g->vn;j++)
{
if(g->E[i][j]>0)
printf("%c->%c (%d/%d)\n",g->V[i]->name,g->V[j]->name,g->f[i][j],g->E[i][j]);
}
}
}
int calcuMaxFlow(pGraph g,int s)
{
int maxFlow=0;
for(int i=0;i<g->vn;i++)
{
if(i==s)
continue;
if(g->f[s][i]>0)
maxFlow+=g->f[s][i];
}
return maxFlow;
}
void main()
{
pGraph g=initGraph();
int s=0,t=g->vn-1;
genericPushRelabel(g,s,t);
int maxFlow=calcuMaxFlow(g,s);
printf("Max Flow is:%d\n",maxFlow);
printFlow(g);
getchar();
}
#include <stdlib.h>
#include <limits.h>
//图节点
typedef struct VertexNode
{
char name;
int h;
int e;
}Vertex,*pVertex;
//图
typedef struct
{
int vn;
int **E; //容量C作为边矩阵的值
pVertex *V;
int **f; //流值
int **rE; // 残留边
}Graph,*pGraph;
//根据算法导论 图26-6初始化图
pGraph initGraph()
{
pGraph g=(pGraph)malloc(sizeof(Graph));
g->vn=6;
pVertex vs=(pVertex)malloc(sizeof(Vertex));
vs->name='s';
pVertex v1=(pVertex)malloc(sizeof(Vertex));
v1->name='1';
pVertex v2=(pVertex)malloc(sizeof(Vertex));
v2->name='2';
pVertex v3=(pVertex)malloc(sizeof(Vertex));
v3->name='3';
pVertex v4=(pVertex)malloc(sizeof(Vertex));
v4->name='4';
pVertex vt=(pVertex)malloc(sizeof(Vertex));
vt->name='t';
g->V=(pVertex*)malloc(g->vn*sizeof(pVertex));
g->V[0]=vs;
g->V[1]=v1;
g->V[2]=v2;
g->V[3]=v3;
g->V[4]=v4;
g->V[5]=vt;
g->E = (int**)malloc(g->vn*sizeof(int*));
g->f= (int**)malloc(g->vn*sizeof(int*));
g->rE= (int**)malloc(g->vn*sizeof(int*));
for(int i=0;i<g->vn;i++)
{
g->E[i]=(int*)malloc(g->vn*sizeof(int));
g->f[i]=(int*)malloc(g->vn*sizeof(int));
g->rE[i]=(int*)malloc(g->vn*sizeof(int));
}
for(int i=0;i<g->vn;i++)
{
for(int j=0;j<g->vn;j++)
{
g->E[i][j]=0;
//g->f[i][j]=0;
}
}
g->E[0][1]=16;
g->E[0][2]=13;
g->E[1][3]=12;
g->E[2][1]=4;
g->E[2][4]=14;
g->E[3][2]=9;
g->E[3][5]=20;
g->E[4][3]=7;
g->E[4][5]=4;
return g;
}
void initResidualNetwork(pGraph g)
{
for(int i=0;i<g->vn;i++)
{
for(int j=0;j<g->vn;j++)
{
g->rE[i][j]=0;
}
}
for(int i=0;i<g->vn;i++)
{
for(int j=0;j<g->vn;j++)
{
if(g->E[i][j]>0)
{
int x=g->E[i][j]-g->f[i][j];
if(x>0)
g->rE[i][j]=x;
if(g->f[i][j]>0)
g->rE[j][i]=g->f[i][j];
}
}
}
}
void initializePreflow(pGraph g,int s)
{
for(int i=0;i<g->vn;i++)
{
g->V[i]->e=g->V[i]->h=0;
}
for(int i=0;i<g->vn;i++)
{
for(int j=0;j<g->vn;j++)
{
g->f[i][j]=0;
}
}
g->V[s]->h=g->vn;
for(int i=0;i<g->vn;i++)
{
if(i != s)
{
g->f[s][i]=g->E[s][i];
g->V[i]->e=g->E[s][i];
g->V[s]->e -= g->E[s][i];
}
}
}
void push(pGraph g,int u,int v)
{
if(g->V[u]->e<=0)
return;
if(g->V[u]->h != g->V[v]->h+1)
return;
if(g->rE[u][v]<=0)
return;
int d=g->V[u]->e < g->rE[u][v] ? g->V[u]->e : g->rE[u][v];
//更新流
if(g->E[u][v]>0)
{
g->f[u][v]+=d;
}
else
{
g->f[v][u]-=d;
}
//更新超额流
g->V[u]->e-=d;
g->V[v]->e+=d;
//更新残存图
if(g->E[u][v]>0)
{
int x=g->E[u][v]-g->f[u][v];
g->rE[u][v]=x;
if(g->f[u][v]>0)
g->rE[v][u]=g->f[u][v];
}
}
//进入函数时,默认保证g->V[u]->e>0
//返回能从u进行push的邻接顶点位置
//返回-1代表残留图中该顶点无邻接点
int relabel(pGraph g,int u)
{
int minh=INT_MAX,minPos;
for(int i=0;i<g->vn;i++)
{
if(i==u)
continue;
if(g->rE[u][i]>0)
{
if(g->V[i]->h<g->V[u]->h)
return i;
else
{
if(g->V[i]->h<minh)
{
minh=g->V[i]->h;
minPos=i;
}
}
}
}
if(minh<INT_MAX)
{
g->V[u]->h=minh+1;
return minPos;
}
else//u没有邻接点时走到这里
return -1;
}
void printFlow2(pGraph g)
{
for(int i=0;i<g->vn;i++)
{
for(int j=0;j<g->vn;j++)
{
if(g->E[i][j]>0)
printf("(%c,%d,%d)->(%c,%d,%d) (%d/%d)\n",
g->V[i]->name,g->V[i]->h,g->V[i]->e,g->V[j]->name,g->V[j]->h,
g->V[j]->e,g->f[i][j],g->E[i][j]);
}
}
printf("\n");
for(int i=0;i<g->vn;i++)
{
for(int j=0;j<g->vn;j++)
{
if(g->rE[i][j]>0)
printf("%c->%c %d\n",g->V[i]->name,g->V[j]->name,g->rE[i][j]);
}
}
}
bool moreOperation(pGraph g,int s,int t)
{
int x=-1;
for(int i=0;i<g->vn;i++)
{
if(i==s || i==t)
continue;
if(g->V[i]->e<=0)
continue;
//push之前,保证g->V[i]->e>0
x=relabel(g,i);
if(x>=0)
{
push(g,i,x);
return true;
}
}
return false;
}
void genericPushRelabel(pGraph g,int s,int t)
{
initializePreflow(g,s);
initResidualNetwork(g);
int v=(s+1)%g->vn;
while(moreOperation(g,s,t))
{
//printFlow2(g);
};
}
void printFlow(pGraph g)
{
for(int i=0;i<g->vn;i++)
{
for(int j=0;j<g->vn;j++)
{
if(g->E[i][j]>0)
printf("%c->%c (%d/%d)\n",g->V[i]->name,g->V[j]->name,g->f[i][j],g->E[i][j]);
}
}
}
int calcuMaxFlow(pGraph g,int s)
{
int maxFlow=0;
for(int i=0;i<g->vn;i++)
{
if(i==s)
continue;
if(g->f[s][i]>0)
maxFlow+=g->f[s][i];
}
return maxFlow;
}
void main()
{
pGraph g=initGraph();
int s=0,t=g->vn-1;
genericPushRelabel(g,s,t);
int maxFlow=calcuMaxFlow(g,s);
printf("Max Flow is:%d\n",maxFlow);
printFlow(g);
getchar();
}