#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "Queue.h"
//图节点
typedef struct VertexNode
{
char name;
}Vertex,*pVertex;
//图
typedef struct
{
int vn;
int **E; //容量C作为边矩阵的值
pVertex *V;
int **f; //流值
}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*));
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));
}
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;
}
//path存储BFS搜索路径,某条路径为(path[i],i)
//s起点,t终点
bool hasPath(pGraph rg,int s,int t,int* path)
{
bool *visited=(bool*)malloc(rg->vn*sizeof(bool));
for(int i=0;i<rg->vn;i++)
{
visited[i]=false;
}
pQ q=initQ(rg->vn);
enQ(q,s);
while(!isEmpty(q))
{
int x=deQ(q);
if(x<0)
break;
visited[x]=true;
for(int i=0;i<rg->vn;i++)
{
if(rg->E[x][i]>0 && !visited[i])
{
visited[i]=true;
path[i]=x;
enQ(q,i);
}
}
}
bool b=visited[t];
free(visited);
if(!b)
return false;
else
return true;
}
pGraph initResidualNetwork(pGraph g)
{
pGraph rg=(pGraph)malloc(sizeof(Graph));//residual network
rg->vn=g->vn;
rg->V=(pVertex*)malloc(g->vn*sizeof(pVertex));
for(int i=0;i<g->vn;i++)
{
rg->V[i]=(pVertex)malloc(sizeof(Vertex));
rg->V[i]->name=g->V[i]->name;
}
rg->E= (int**)malloc(g->vn*sizeof(int*));
for(int i=0;i<g->vn;i++)
{
rg->E[i]=(int*)malloc(g->vn*sizeof(int));
}
for(int i=0;i<g->vn;i++)
{
for(int j=0;j<g->vn;j++)
{
rg->E[i][j]=g->E[i][j];
}
}
return rg;
}
void printPath(int *path,int n)
{
for(int i=1;i<n;i++)
printf("%d->%d",path[i],i);
printf("\n");
}
int FordFulkson(pGraph g,int s,int t)
{
int maxFlow=0;
pGraph rg=initResidualNetwork(g);
int *path=(int*)malloc(g->vn*sizeof(int));
while(hasPath(rg,s,t,path))
{
int minF=INT_MAX;
for(int i=1;i<g->vn;i++)
{
if(rg->E[path[i]][i]<minF)
minF=rg->E[path[i]][i];
}
//printPath(path,g->vn);
for(int i=t;i>s;i=path[i])
{
int u=path[i],v=i;
if(g->E[u][v]>0)
{
g->f[u][v]+=minF;
rg->E[u][v]=g->E[u][v]-g->f[u][v];
}
else if(g->E[v][u]>0)
{
g->f[v][u]-=minF;
rg->E[u][v]=g->f[v][u];
}
}
maxFlow+=minF;
}
return maxFlow;
}
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]);
}
}
}
void main()
{
pGraph g=initGraph();
int max=FordFulkson(g,0,5);
printf("%d\n",max);
printFlow(g);
getchar();
}
算法导论 最大流 FordFulkson
最新推荐文章于 2023-03-07 21:47:56 发布