HDU 4411 Arrest 费用流
来源:互联网 发布:联通网络机顶盒破解 编辑:程序博客网 时间:2024/05/21 20:24
费用流是每次找最短路然后沿着这条路增广,然后这条路因为增广了,所以就流量为0,相当于不存在了,所以可以继续找最短路,不怕出现重复,然后求的是全图的,这点切记
有n+1个城市,0市为警察局所在城市其中有k个警察,在其他n个城市中,均有小偷。有m条路,每条路有其特定路程,求k个警察将n个城市的小偷全抓捕到0市的最短路程。其中抓小偷必须从1、2、3、、、n按照城市号码严格递增顺序抓。
最小费用流的问题。样例输出解释:0->1->3(不抓小偷)->2->3->1->0。路程和为3+2+2+2+2+3=14。
设置超级源点s,超级汇点t。将0点与s和t建立容量为k,费用为0的边,并将其他n点拆掉。n个点与0点建立容量1费用为两点最短路的边,同时n个被拆出来的点与t建立容量为1费用为两点最短路的边,n个点与其被拆出来的点建立容量为1费用足够小的边(足够小的意思是保证不会出现s->0->t),跑一边最小费用,最后输出的时候把n个足够小费用加回去。
#include <iostream>#include <stdio.h>using namespace std;const int oo=1e9;const int maxm=1111111;const int maxn=220;const int ff=100000;int node,src,dest,edge;int head[maxn],p[maxn],dis[maxn],q[maxn],vis[maxn];struct edgenode{ int to; int flow; int cost; int next;} edges[maxm];void prepare(int _node,int _src,int _dest);void addedge(int u,int v,int f,int c);bool spfa();inline int min(int a,int b){ return a<b?a:b;}inline void prepare(int _node,int _src,int _dest){ node=_node; src=_src; dest=_dest; for (int i=0; i<node; i++) { head[i]=-1; vis[i]=false; } edge=0;}void addedge(int u,int v,int f,int c){ edges[edge].flow=f; edges[edge].cost=c; edges[edge].to=v; edges[edge].next=head[u]; head[u]=edge++; edges[edge].flow=0; edges[edge].cost=-c; edges[edge].to=u; edges[edge].next=head[v]; head[v]=edge++;}bool spfa(){ int i,u,v,l,r=0,tmp; for (i=0; i<node; i++) dis[i]=oo; dis[q[r++]=src]=0; p[src]=p[dest]=-1; for (l=0; l!=r; ((++l>=maxn)?l=0:1)) { for (i=head[u=q[l]],vis[u]=false; i!=-1; i=edges[i].next) { if (edges[i].flow&&dis[v=edges[i].to]>(tmp=dis[u]+edges[i].cost)) { dis[v]=tmp; p[v]=i^1; if (vis[v]) continue; vis[q[r++]=v]=true; if (r>=maxn) r=0; } } } return p[dest]>=0;}int spfaflow(){ int i,ret=0,delta; while (spfa()) { for (i=p[dest],delta=oo; i>=0; i=p[edges[i].to]) { delta=min(delta,edges[i^1].flow); } for (int i=p[dest]; i>=0; i=p[edges[i].to]) { edges[i].flow+=delta; edges[i^1].flow-=delta; } ret+=delta*dis[dest]; } return ret;}//以上是费用流模板int a[maxn][maxn];int main(){ int n,m,k; while(~scanf("%d%d%d",&n,&m,&k) && (n || m || k)) { //init(); int s=n*2+1; int t=s+1; prepare(n*2+3,s,t); //for(int i=0; i<=n; i++) // for(int j=0; j<=n; j++) for(int i=0; i<m; i++) for(int j=0; j<m; j++) if (i!=j) a[i][j]=oo; else a[i][j]=0; //while(m--) for(int i=0; i<m; i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); a[u][v]=a[v][u]=min(w,a[u][v]); } for(int l=0;l<=n;l++)//Floyd求最短路 for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) if(a[i][l]<oo && a[l][j]<oo && a[i][l]+a[l][j]<a[i][j]) a[i][j]=a[i][l]+a[l][j]; addedge(s,0,k,0);//源点与0点,容量为k,费用为0 addedge(0,t,k,0);//汇点与0点,容量为k,费用为0 for(int i=1; i<=n; i++) { for(int j=i+1; j<=n; j++) { addedge(i+n,j,1,a[i][j]);//先到i点再到j点 } addedge(0,i,1,a[0][i]);//0点到i点,容量为1,费用为最短路 addedge(i,i+n,1,-ff);//拆点,cost值设为适当小的值,以免导致s->0->t addedge(i+n,t,1,a[0][i]);//i点到0点,容量为1,费用为最短路 } printf("%d\n",spfaflow()+ff*n); } return 0;}
0 0
- hdu-4411-Arrest-费用流
- 【HDU】4411 Arrest 费用流
- HDU 4411 Arrest 费用流
- HDU 4411 Arrest 费用流
- HDU 4411 Arrest 费用流
- Arrest HDU 费用流
- hdu 4411 Arrest(费用流)
- HDU 4411 Arrest 最小费用流
- hdu 4411 Arrest(最小费用最大流)
- HDU 4411 Arrest 最小费用流
- hdu 4411 Arrest 费用流模板
- hdu 4411 Arrest (最小费用最大流)
- HDU 4411 Arrest(费用流)
- hdu 4411 Arrest【最小费用流】
- HDU 4411 - Arrest(网络流‘最小费用最大流)
- HDU 4411 Arrest 费用流 建边技巧
- HDU 4411 Arrest 最小费用最大流(题意+建图)
- HDU 4411 Arrest(Floyd+最小费用最大流)
- WebSocket(1)-- WebSocket API简介
- Five-People:常用控件及其属性(RadioButton,CheckBox,align,margin,padding)使用方法
- virual box快速安装max系统
- Caffe+Ubuntu14.04+CUDA7.5安装笔记
- 获取java中src目录的方法
- HDU 4411 Arrest 费用流
- WebSocket(2)--为什么引入WebSocket协议
- android仿qq聊天界面的的布局适配器的写法
- View的事件分发机制
- 专业版V9.1SP1提示"运行时错误,-2147417848(80010108)
- WebSocket(3)-- WebSocket协议简介
- ACE 环境配置
- 手摘
- WebSocket(4)-- WebSocket与TCP、Http的关系