HDU 4289 Control (最大流+拆点)
2014-08-13 11:33
344 查看
http://acm.hdu.edu.cn/showproblem.php?pid=4289
题目讲的是有一些恐怖分子要从S市去往D市,要求在一些城市中安排特工,保证一定能够抓住恐怖分子,因为安排特工需要一定的费用,所以希望找出最小的花费。
思路:可以把每个城市,即每个点拆分成进来的点和出去的点,如x点分成x和x+n,两点连接的边权值为x点上安排特工的费用。而如果x和y两点有连线,则连接x+n,y,然后求从S市到达D市的最大流。之所以能这样求,是因为在求最大流的过程中每次所更新的流量是所有边中最小的,这样最小流量的边就是每个点拆分开的两点之间的连线,这样求的过程中对最大流有限制的就是所有点上的花费了。
View Code
题目讲的是有一些恐怖分子要从S市去往D市,要求在一些城市中安排特工,保证一定能够抓住恐怖分子,因为安排特工需要一定的费用,所以希望找出最小的花费。
思路:可以把每个城市,即每个点拆分成进来的点和出去的点,如x点分成x和x+n,两点连接的边权值为x点上安排特工的费用。而如果x和y两点有连线,则连接x+n,y,然后求从S市到达D市的最大流。之所以能这样求,是因为在求最大流的过程中每次所更新的流量是所有边中最小的,这样最小流量的边就是每个点拆分开的两点之间的连线,这样求的过程中对最大流有限制的就是所有点上的花费了。
/*Dinic算法求最大流*/ #include<stdio.h> #include<string.h> #include<iostream> #define point_MAX 10000 #define edge_MAX 100000 #define INF_MAX 999999999 using namespace std; struct EDGE { int to;/*指向的点*/ int next;/*指向的下一条邻边*/ int w;/*权值*/ }edge[edge_MAX]; int len;/*边的数量*/ int point[point_MAX]; int Vertex,Edge; int d[point_MAX]; void init()/*初始化*/ { len=0; memset(point,0,sizeof(point)); } int add_edge(int a,int b,int w)/*添加由a指向b的权值为w的边*/ { len++; edge[len].w=w; edge[len].to=b; edge[len].next=point[a]; point[a]=len; return 0;/*无重边,插入*/ } int bfs(int s) { int q[point_MAX],front=0,rear=1,j,t,i; q[0]=s; memset(d,-1,sizeof(d));/**/ d[s]=0; while(front<rear) { t=q[front++]; for(j=point[t];j;j=edge[j].next) { if(d[edge[j].to]==-1&&edge[j].w>0) { d[edge[j].to]=d[t]+1; q[rear++]=edge[j].to;/*逐层增加*/ } } } if(d[Vertex]>=0) return 1; return 0; } long long min(long long a,long long b) { return a<b?a:b; } long long dinic(int t,long long sum)/*寻找增广路*/ { int i,os,j; long long a; if(t==Vertex)/*如果已经找到汇点,返回sum*/ return sum; os=sum; for(i=point[t];i&∑i=edge[i].next) { if(d[edge[i].to]==d[t]+1&&edge[i].w>0)/*可行流,即增广路*/ { a=dinic(edge[i].to,min(sum,edge[i].w)); edge[i].w-=a; for(j=point[edge[i].to];edge[j].to!=t;j=edge[j].next); edge[j].w+=a;/*处理反向边*/ sum-=a; } } return os-sum; } long long DINIC(int s)/*DINIC算法*/ { long long ans=0; while(bfs(s))/*遍历整个图,判断是否已经完成最大流*/ ans+=dinic(s,INF_MAX);/*添加所能增加的流量*/ return ans; } int main() { int i,j,x,y,w,S,D; int cost[205]; while(scanf("%d%d",&Vertex,&Edge)!=EOF) { init(); memset(cost,0,sizeof(cost)); scanf("%d%d",&S,&D); for(i=1;i<=Vertex;i++) { scanf("%d",&cost[i]); add_edge(i,i+Vertex,cost[i]); add_edge(i+Vertex,i,0); } for(i=0;i<Edge;i++) { scanf("%d%d",&x,&y); add_edge(x+Vertex,y,INF_MAX); add_edge(y,x+Vertex,0); add_edge(y+Vertex,x,INF_MAX);/*添加反向边*/ add_edge(x,y+Vertex,0); } Vertex=D+Vertex; //cout<<"=="<<endl; printf("%lld\n",DINIC(S));/*以S为源点,Vertex为汇点*/ } return 0; }
View Code
相关文章推荐
- HDU 4289 Control(最大流、最小割)
- HDU 4289 Control (最小割最大流)
- HDU-4289-Control(最大流+拆点)
- hdu 4289 Control (最大流)
- HDU 4289 Control (网络流,最大流)
- hdu 4289 Control 最小割最大流
- hdu4289——Control(最大流最小割+SAP)
- HDU-4289-Control(最大流)
- hdu 4289 Control(网络流 最大流+拆点)(模板)
- hdu 4289 Control (最大流)
- 最大流最小割-HDU-4289-Control
- HDU 4289 - Control(最大流-ISAP模板)
- HDU 4289 Control 最大流
- 【HDU】4289 Control 最大流
- hdu 4289 Control 【图论-网络流-最大流-拆点】
- HDU 4289 Control(最大流+拆点)
- hdu 4289 Control【最大流Dinic----拆点+最大流最小割定理】
- HDU 4289 Control 最小割最大流 拆点
- HDU 4289 Control(拆点,最大流)
- I - Control - HDU 4289 (最大流)