hdu 4411 Arrest【最小费用流】
来源:互联网 发布:淘宝网宠物店能信吗 编辑:程序博客网 时间:2024/05/29 10:57
题目链接
题意:
给定一个有(n+1)个节点的边权图,其中警察局在0点,其他n个点各有一个黑手党,现在警察局派出k个警察去抓黑手党,并逮捕会警察局,一旦黑手党i被抓,他会向黑手党i-1报信,任务就会失败,求使任务成功的的最小花费?
思路:
要使黑手党之间不能通讯,必须以1到n的顺序来抓捕,那么每个警察的抓捕顺序只能从小到大。警察从一个城市到另一个城市一定走的是两个城市间的最短路。
首先可以floyd求dis[i][j];
建图如下:
(1)n个城市拆成入点和出点,之间建边,容量为1,花费为-1000000(一个足够小的数,保证这条边一定被通过)
(2)源点s到0,容量为k,花费为0
(3)0到汇点t,容量为k,花费为0;0到第i个城市的入点,容量为1,花费为dis[0][i]
(4)对所有i<j,建容量为1,花费为dis[i][j]的边
(5)第i个城市的出点到汇点t,容量为1,花费为dis[0][i]
固定流量为k,用最小费用流跑一遍,答案加上n*1000000。
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<algorithm>#include<map>#include<string>#include<queue>#include<vector>#include<list>#include<bitset>//#pragma comment(linker,"/STACK:1024000000,1024000000")using namespace std;typedef long long ll;#define INF 0x3f3f3f3f#define MAX_V 1005typedef pair<int,int> P;struct edge{ int to,cap,cost,rev;};int V;vector<edge> G[MAX_V];int h[MAX_V];int dist[MAX_V];int prevv[MAX_V],preve[MAX_V];void add_edge(int from,int to,int cap,int cost){ G[from].push_back((edge) { to,cap,cost,G[to].size() }); G[to].push_back((edge) { from,0,-cost,G[from].size()-1 });}int min_cost_flow(int s,int t,int f){ int res=0; fill(h,h+V,0); while(f>0) { priority_queue<P, vector<P> ,greater<P> >que; fill(dist,dist+V,INF); dist[s]=0; que.push(P(0,s)); while(!que.empty()) { P p=que.top(); que.pop(); int v=p.second; if(dist[v]<p.first) continue; for(int i=0; i<G[v].size(); i++) { edge &e=G[v][i]; if(e.cap>0&&dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]) { dist[e.to]=dist[v]+e.cost+h[v]-h[e.to]; prevv[e.to]=v; preve[e.to]=i; que.push(P(dist[e.to],e.to)); } } } if(dist[t]==INF) { return -1; } for(int v=0; v<V; v++) h[v]+=dist[v]; int d=f; for(int v=t; v!=s; v=prevv[v]) { d=min(d,G[prevv[v]][preve[v]].cap); } f-=d; res+=d*h[t]; for(int v=t;v!=s;v=prevv[v]) { edge &e=G[prevv[v]][preve[v]]; e.cap-=d; G[v][e.rev].cap+=d; } } return res;}int n,m,K;int dis[205][205];int main(){ while(~scanf("%d%d%d",&n,&m,&K)&&n+m+K) { V=2*n+5; int s=V-2,t=V-1; for(int i=0;i<MAX_V;i++) G[i].clear(); memset(dis,0x3f,sizeof dis); for(int i=1;i<=m ;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); dis[u][v]=dis[v][u]=min(dis[u][v],w); } for(int k=0;k<=n;k++) for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) { dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); } add_edge(s,0,K,0); add_edge(0,t,K,0); for(int i=1;i<=n;i++) { add_edge(0,i,1,dis[0][i]); add_edge(i,n+i,1,-1000000); add_edge(n+i,t,1,dis[0][i]); } for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { if(dis[i][n]<INF) add_edge(i+n,j,1,dis[i][j]); } } int ans=min_cost_flow(s,t,K); ans+=n*1000000; printf("%d\n",ans); } return 0;}
1 0
- 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+最小费用最大流)
- 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(费用流)
- hdu4411 Arrest 最小费用流
- xpath语法规范
- Android中listview加载数据的时候出现空白页
- DDR3 内存带宽计算
- 归并排序
- PHP Date()函数详细参数
- hdu 4411 Arrest【最小费用流】
- JDK
- cookie与session的区别
- 空
- 如何在 ASP.NET MVC 中集成 AngularJS(1)
- Ceph学习一
- WebCollector初探——微博信息爬取
- 插入排序
- Cloudera Manager 中Oozie 配置HIVE workflow