最大流笔记

看了一个下午,似懂非懂就是不懂啊。。
先码住!建图也是巨难啊!!
大概思路是bfs:
每次bfs都过一遍,如果还可以找到增广路就记录答案
每次整理答案的时候加上去,同时一个奇妙的操作:前驱加后继减。
我个人理解觉得和dfs完了取消标记一样的感觉,就是为了消除这一步对以后的行为造成的影响,方便找到最优解。`

1.存储

struct p{
 int s,e,num;
} flow[maxn];
//没毛病
for(int i=1;i<=m;i++){
  int u,v,w;
  scanf("%d%d%d",&u,&v,&w);
  flow[i].s=u;
  flow[i].e=v;
  flow[i].num=w;
 }

2.重点 然而我不会啊


//大概思路 EK(start,end) 如果还能找到就更新
int EK(int s_pos,int e_pos){
 int minn;
 while(bfs(s_pos,e_pos)){
  minn=inf;
  //结构体就是遍历的时候麻烦· 是倒着遍历的
  for(int i=e_pos;i!=s;i=flow[pre[i]].s){
   minn=min(minn,flow[pre[i]].num);
   //flow是从pre[i]出发找到的增广路
  }
  for(int i=e_pos;i!=s;i=flow[pre[i]].s){
   flow[pre[i]].num-=minn;
   //这里我不是很明白。。。
   flow[pre[i]+m].num+=minn;
  }
  max_flow+=minn;
 }
 return max_flow;
}

bfs具体实现


bool  bfs(int s,int e){
 //初始化  只要设置成不一样的 
 s_pos=-1,e_pos=0;
 memset(wh,0,sizeof wh);
 //标记已经访问
 wh[s]=1;
 q[0]=s;//q是个队列来着
 while(s_pos!=e_pos){
  cur_pos=q[++s_pos];/*
  for(int i=1;i<=n;++i){ 
   if(!wh[i] && flow[cur_pos][i]>0){
    wh[i]=1;//标记往下走 
    pre[i]=cur_pos;
    if(i==e) return 1;
    //?
    q[++e_pos]=i;
   }
  } */
  for(int i=1;i<=2*m;i++){
   if(cur_pos == flow[i].s &&
   !wh[flow[i].e] && flow[i].num){
    wh[flow[i].e]=1;
    pre[flow[i].e]=i;
    if(flow[i].e == e) return 1;
    q[++e_pos]=flow[i].e;
   }
  }
 }
 return 0;
}

这样还是会超时,待我再看一看。

发布了24 篇原创文章 · 获赞 2 · 访问量 972

猜你喜欢

转载自blog.csdn.net/weixin_43521836/article/details/88914556
今日推荐