算法导论 最大流 FordFulkson

#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();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值