最大流Dinic C语言实现(详细)--poj 3281
2017-03-12 19:08
316 查看
//Dinic最大的不同就是分层找增长路径。。。, //我们知道一般是用BFS来找一个增长路径,从中心一层一层地向外扩散 //但是Dinic也是一层一层的向外找,但是它每层只选择一个一个顶点就跳到下一层中接着寻找 #include<stdio.h> #define N 1000 #define MAX 0x3f3f3f3f #define min(x,y) ((x>y)?(y):(x))//定义宏 int map ;//图 int dis ;//来表示分层图距离 int q[10000],h,r;//手工队列,h为队首,r为队尾 int source,sink;//顶点的最大编号sink,最小编号source=0 int BFS(void) { int i,j; memset(dis,0xff,sizeof(dis)); dis[0]=0; h=-1;r=0; q[0]=0; while(h<r) { j=q[++h]; for(i=0;i<=sink;i++) { if(dis[i]<0&&map[j][i]>0) { dis[i]=dis[j]+1;//来决定每个点与源点的距离,也就是分层。。。 q[++r]=i; } } } if(dis[sink]>0) return 1; else return 0; } int find(int x,int low)//表示已经到了x顶点,并且此时从源点到x顶点的这一段路中可以达到的最大流量 { int i,a=0; if(x==sink)//如果到了汇点,返回最大流量 return low; for(i=0;i<=sink;i++) { if(map[x][i]>0&&dis[i]==dis[x]+1&&(a=find(i,min(low,map[x][i]))))//这就是每一层找一个,然后接着找下一层 { map[x][i]-=a;//正向边流量增加 map[i][x]+=a;//反向边流量减少 return a; } } return 0; } int main() { int ans,tans,n,f,d,i,f_sum,d_sum,j,tmp; while(~scanf("%d%d%d",&n,&f,&d)) { memset(map,0,sizeof(map)); source=0;sink=2*n+f+d+1; for(i=1;i<=f;i++)map[source][i]=1;//构建图,这道题有点特殊的构图方式 for(i=1;i<=d;i++)map[2*n+f+i][sink]=1; for(i=1;i<=n;i++)map[f+i][f+n+i]=1; for(i=1;i<=n;i++) { scanf("%d%d",&f_sum,&d_sum); for(j=1;j<=f_sum;j++) { scanf("%d",&tmp); map[tmp][f+i]=1; } for(j=1;j<=d_sum;j++) { scanf("%d",&tmp); map[f+n+i][2*n+f+tmp]=1; } } ans=0; while(BFS()) { while(tans=find(0,0x3f3f3f3f)) ans+=tans; } printf("%d\n",ans); } }
//还有一种实现方式,这是从汇点开始到源点结束的。。。。。 #define MAXV 410 #define INF INT_MAX #define min(a,b) (a>b?b:a) int res[MAXV][MAXV]; int dis[MAXV]; int n,maxflow; int bfs(){ int k; queue<int> q; memset(dis,-1,sizeof(dis)); dis =0; q.push(n); while(!q.empty()){ k=q.front(); q.pop(); for(int i=0;i<n;i++){ if(dis[i]==-1 && res[i][k]){ dis[i] = dis[k] + 1; q.push(i); } } if(k==0) return 1; } return 0; } int dfs(int cur,int cp){ if(cur==n) return cp; int tmp=cp,t; for(int i=0;i<=n && tmp;i++){ if(dis[i]+1==dis[cur] && res[cur][i]){ t=dfs(i,min(res[cur][i],tmp)); res[cur][i]-=t; res[i][cur]+=t; tmp-=t; } } return cp-tmp; }
相关文章推荐
- POJ 3281-Dining(最大流入门,建图详细解析)
- POJ 1274The Perfect Stall (二分图最大匹配问题,匈牙利算法实现)
- POJ 3281 最大流水题
- POJ 3281 - Dining 简单构图最大流..
- Poj 3281 最大流入门
- poj 3281,最大流,牛吃食物问题
- POJ 2377 最大生成树 prim实现
- poj 3281 最大流
- poj 3281 Dining 网络流-最大流-建图的题
- poj 3281 Dining 网络流-最大流-建图的题
- POJ 3281 —— 最大流
- POJ 3281 简单构图+最大流
- poj3281——Dining(最大流)
- POJ 3281 Dining(最大流)
- poj 3281 最大流建图
- poj 3281 Dining (最大流)
- poj 3281 最大流 拆点构图,关键在于构图
- poj 3281 Dining 【最大流】
- poj 1459 Power Network : 最大网络流 dinic算法实现
- poj 3281 最大流