作业

来源:互联网 发布:python tkiner 编辑:程序博客网 时间:2024/05/22 13:43

网络流 Dinic算法

Dinic

1、BFS对点分层;
2、源点开始,DFS从前一层向后一层寻找增广路;
3、当找到汇点,也就是找到增广路,更新,进行增广;
4、增广,不结束,回溯,找新的增广路;
5、当找不到增广路,跳到1.进行BFS,如果BFS无法找到汇点,结束;

增广路径

若P是图G中一条连通两个未匹配顶点的路径,并且属于M的边和不属于M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广路径

以POJ1273为例
Drainage Ditches
Description
Every time it rains on Farmer John’s fields, a pond forms over Bessie’s favorite clover patch. This means that the clover is covered by water for awhile and takes quite a long time to regrow. Thus, Farmer John has built a set of drainage ditches so that Bessie’s clover patch is never covered in water. Instead, the water is drained to a nearby stream. Being an ace engineer, Farmer John has also installed regulators at the beginning of each ditch, so he can control at what rate water flows into that ditch.
Farmer John knows not only how many gallons of water each ditch can transport per minute but also the exact layout of the ditches, which feed out of the pond and into each other and stream in a potentially complex network.
Given all this information, determine the maximum rate at which water can be transported out of the pond and into the stream. For any given ditch, water flows in only one direction, but there might be a way that water can flow in a circle.
Input
The input includes several cases. For each case, the first line contains two space-separated integers, N (0 <= N <= 200) and M (2 <= M <= 200). N is the number of ditches that Farmer John has dug. M is the number of intersections points for those ditches. Intersection 1 is the pond. Intersection point M is the stream. Each of the following N lines contains three integers, Si, Ei, and Ci. Si and Ei (1 <= Si, Ei <= M) designate the intersections between which this ditch flows. Water will flow through this ditch from Si to Ei. Ci (0 <= Ci <= 10,000,000) is the maximum rate at which water will flow through the ditch.
Output
For each case, output a single integer, the maximum rate at which water may emptied from the pond.
Sample Input
5 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10
Sample Output
50
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
好(hou)心(yan)翻(wu)译(chi)~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
题目描述 Description
在农夫约翰的农场上,每逢下雨,Bessie最喜欢的三叶草地就积聚了一潭水。这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间。因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没的烦恼(不用担心,雨水会流向附近的一条小溪)。作为一名一流的技师,农夫约翰已经在每条排水沟的一端安上了控制器,这样他可以控制流入排水沟的水流量。

农夫约翰知道每一条排水沟每分钟可以流过的水量,和排水系统的准确布局(起点为水潭而终点为小溪的一张网)。需要注意的是,有些时候从一处到另一处不只有一条排水沟。

根据这些信息,计算从水潭排水到小溪的最大流量。对于给出的每条排水沟,雨水只能沿着一个方向流动,注意可能会出现雨水环形流动的情形。

输入描述 Input Description
第1行: 两个用空格分开的整数N (0 <= N <= 200) 和 M (2 <= M <= 200)。N是农夫John已经挖好的排水沟的数量,M是排水沟交叉点的数量。交点1是水潭,交点M是小溪。

第二行到第N+1行: 每行有三个整数,Si, Ei, 和 Ci。Si 和 Ei (1 <= Si, Ei <= M) 指明排水沟两端的交点,雨水从Si 流向Ei。Ci (0 <= Ci <= 10,000,000)是这条排水沟的最大容量。

输出描述 Output Description
输出一个整数,即排水的最大流量。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BFS->DFS->增广->回溯->BFS->如果没找到增广结束否则继续= =
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

代码:

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define MAX1 202#define MAX2 202*202#define INF 0x3f3f3f3fstruct Edge{    int v,f,next;}edge[MAX2];int n,m,cnt;int first[MAX1],level[MAX1],q[MAX1];void init(){    cnt=0;    memset(first,-1,sizeof(first));}void addedge(int u,int v,int f){    edge[cnt].v=v;    edge[cnt].f=f;    edge[cnt].next=first[u];    first[u]=cnt++;    edge[cnt].v=u;    edge[cnt].f=0;    edge[cnt].next=first[v];    first[v]=cnt++;}int bfs(int s,int t){    memset(level,0,sizeof(level));    level[s]=1;    int front=0,rear=1;    q[front]=s;    while(front<rear){        int x=q[front++];        if(x==t) return 1;        for(int e=first[x];e!=-1;e=edge[e].next){            int v=edge[e].v,f=edge[e].f;            if(!level[v]&&f){                level[v]=level[x]+1;                q[rear++]=v;            }        }    }    return 0;  }int dfs(int u,int maxf,int t){    if(u==t) return maxf;    int ret=0;    for(int e=first[u];e!=-1;e=edge[e].next){        int v=edge[e].v,f=edge[e].f;        if(level[u]+1==level[v]&&f){            int Min=min(maxf-ret,f);            f=dfs(v,Min,t);            edge[e].f-=f;            edge[e^1].f+=f;            ret+=f;            if(ret==maxf) return ret;        }    }    return ret;}int dinic(int s,int t){    int ans=0;    while(bfs(s,t)){        ans+=dfs(s,INF,t);        //printf("\n%d\n",ans);    }    return ans;}int main(){    init();    //freopen("test.txt","w",stdin);    scanf("%d%d",&n,&m);    int u,v,f,all;    for(int i=0;i<n;i++){        scanf("%d%d%d",&u,&v,&f);        addedge(u,v,f);    }    all=dinic(1,m);    printf("%d",all);}

还有一道Dinic题,不过输入方式有点恶心= =次元传送

0 0
原创粉丝点击