看了一个下午,似懂非懂就是不懂啊。。
先码住!建图也是巨难啊!!
大概思路是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;
}
这样还是会超时,待我再看一看。