一张图中每条边都有同一时间能承载的最大数据量,求最大网络流即求从起点到终点同一时间能运输的最大数据量。
找到一条从起点到终点的路,那么这条路上运输的数据量为权值最小的边的权值,然后再依次做下去,但这样过早地阻塞了后面的流,会造成无法得到最优解。解决的方法是添加一条反向边,如果边<u,v>流过了k,那么反向边<v,u>的权值即为n-k;这样就形成了一张残余网络;
Dinic算法:^_^据说^_^从终点到起点所经过的边的数量越少,那么效率就越高。所以说可以先做一遍BFS,找出每一个点的层数,然后在DFS时就只做自己下一层的点;找出一条路上的最小值后更新每个点的正边(减少)和反边(增加);
Dinic代码:
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
int flag[210],dis[210],n,m,num=2,fir[210],dl[500],head,tail;
struct ppp{
int go,nxt,val;
}e[500];
void ini(){
num=2; head=0; tail=1;
memset(e,0,sizeof(e));
memset(fir,0,sizeof(fir));
memset(dl,0,sizeof(dl));
memset(flag,0,sizeof(flag));
}
void add(int a,int b,int c,int rc){
e[num].go=b; e[num].val=c;
e[num].nxt=fir[a]; fir[a]=num++;
e[num].go=a; e[num].val=rc;
e[num].nxt=fir[b]; fir[b]=num++;
}
int BFS(){
queue<int> q;
q.push(1);
memset(dis,0x3f,sizeof(dis));
dis[1]=0;
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=fir[u];i;i=e[i].nxt){
int v=e[i].go;
if(e[i].val>0 && dis[v]==0x3f3f3f3f){
dis[v]=dis[u]+1;
q.push(v);
}
}
}
return dis[n]<0x3f3f3f3f;
}
int min(int x,int y){
if(x>y) return y; return x;
}
int dfs(int s,int f){
if(s==n) return f;
for(int i=fir[s];i;i=e[i].nxt){
int t=e[i].go,c=e[i].val;
if(dis[t]==dis[s]+1 && c>0){
int flow=dfs(t,min(f,c));
if(flow){
e[i].val-=flow;
e[i^1].val+=flow;
return flow;
}
}
}
return 0;
}
int max_ans(int s){
int ans=0;
while(BFS()){
int flow;
while(flow=dfs(s,0x3f3f3f3f)){
ans+=flow;
}
}
return ans;
}
int main(){
freopen("水渠测试数据.txt","r",stdin);
while(scanf("%d%d",&m,&n)!=EOF){
ini();
int i,j;
for(i=1;i<=m;i++){
int a,b,c; scanf("%d%d%d",&a,&b,&c);
add(a,b,c,0);
}
printf("%d\n",max_ans(1));
}
}
!!QUESTION!!:
求大神回答这两种写法有什么不同,都可以AC,但在不同的题中效率不一样:
1:
int dfs(int s,int f){
if(s==n) return f;
for(int i=fir[s];i;i=e[i].nxt){
int t=e[i].go,c=e[i].val;
if(dis[t]==dis[s]+1 && c>0){
int flow=dfs(t,min(f,c));
if(flow){
e[i].val-=flow;
e[i^1].val+=flow;
return flow;
}
}
}
return 0;
}
2:int dfs(int s,int f){
int p=f;
if(s==n) return f;
for(int i=fir[s];i;i=e[i].nxt){
int t=e[i].go,c=e[i].val;
if(dis[t]==dis[s]+1 && c>0){
int flow=dfs(t,min(f,c));
e[i].val-=flow;
e[i^1].val+=flow;
f-=flow;
}
}
return p-f;
}