题目描述:

Description
There are (N+1) cities on TAT island. City 0 is where police headquarter located. The economy of other cities numbered from 1 to N ruined these years because they are all controlled by mafia. The police plan to catch all the mafia gangs in these N cities all over the year, and they want to succeed in a single mission. They figure out that every city except city 0 lives a mafia gang, and these gangs have a simple urgent message network: if the gang in city i (i>1) is captured, it will send an urgent message to the gang in city i-1 and the gang in city i -1 will get the message immediately.
The mission must be carried out very carefully. Once a gang received an urgent message, the mission will be claimed failed.
You are given the map of TAT island which is an undirected graph. The node on the graph represents a city, and the weighted edge represents a road between two cities(the weight means the length). Police headquarter has sent k squads to arrest all the mafia gangs in the rest N cities. When a squad passes a city, it can choose to arrest the gang in the city or to do nothing. These squads should return to city 0 after the arrest mission.
You should ensure the mission to be successful, and then minimize the total length of these squads traveled.

Input
There are multiple test cases.
Each test case begins with a line with three integers N, M and k, here M is the number of roads among N+1 cities. Then, there are M lines. Each of these lines contains three integers X, Y, Len, which represents a Len kilometer road between city X and city Y. Those cities including city 0 are connected.
The input is ended by “0 0 0”.
Restrictions: 1 ≤ N ≤ 100, 1 ≤ M ≤ 4000, 1 ≤ k ≤ 25, 0 ≤ Len ≤ 1000

Output
For each test case,output a single line with a single integer that represents the minimum total length of these squads traveled.

Sample Input

3 4 2
0 1 3
0 2 4
1 3 2
2 3 2
0 0 0

Sample Output

14

题目分析:

有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 <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
typedef long long ll;
const int MINC = -1000000;//适当小的值
const int INF = 0x3f3f3f3f;
const int MAXN = 220;
const int MAXM = 40040;struct node
{int u,v,cap,flow,cost,next;
}edge[MAXM];int map[MAXN][MAXN];
int num;
int n,m,k;
int head[MAXN];
int id;
int pre[MAXN],dis[MAXN];
bool vis[MAXN];
int s,t;void init()
{id=0;memset(head,-1,sizeof(head));
}void addedge(int u, int v, int cap, int cost)
{edge[id].u=u;edge[id].v=v;edge[id].cap=cap;edge[id].flow=0;edge[id].cost=cost;edge[id].next=head[u];head[u]=id++;edge[id].u=v;edge[id].v=u;edge[id].cap=0;edge[id].flow=0;edge[id].cost=-cost;edge[id].next=head[v];head[v]=id++;
}bool spfa(int s,int t)
{queue<int>q;memset(dis,INF,sizeof(dis));memset(vis,false,sizeof(vis));memset(pre,-1,sizeof(pre));dis[s]=0;vis[s]=true;q.push(s);while(!q.empty()){int u=q.front();q.pop();vis[u]=false;for(int i=head[u]; i!=-1; i=edge[i].next){int v=edge[i].v;if(edge[i].cap > edge[i].flow && dis[v] > dis[u]+edge[i].cost){dis[v]=dis[u]+edge[i].cost;pre[v]=i;if(!vis[v]){vis[v]=true;q.push(v);}}}}if (pre[t]==-1) return false;else return true;
}int minCostMaxflow(int s,int t)//本题是寻找最小费用,因此返回cost
{int flow=0,cost=0;while(spfa(s,t)){int Min=INF;for(int i=pre[t]; i!=-1; i=pre[edge[i^1].v]){Min=min(edge[i].cap-edge[i].flow,Min);}for(int i=pre[t]; i!=-1; i=pre[edge[i^1].v]){edge[i].flow+=Min;edge[i^1].flow-=Min;cost+=edge[i].cost*Min;}flow+=Min;}//return flow;return cost;
}int main()
{while(~scanf("%d%d%d",&n,&m,&k) && (n || m || k)){init();s=n*2+1;t=s+1;for(int i=0; i<=n; i++)for(int j=0; j<=n; j++)if (i!=j) map[i][j]=INF;else map[i][j]=0;while(m--){int u,v,w;scanf("%d%d%d",&u,&v,&w);map[u][v]=map[v][u]=min(w,map[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(map[i][l]<INF && map[l][j]<INF && map[i][l]+map[l][j]<map[i][j])map[i][j]=map[i][l]+map[l][j];addedge(s,0,k,0);//源点与0点,容量为k,费用为0addedge(0,t,k,0);//汇点与0点,容量为k,费用为0for(int i=1; i<=n; i++){for(int j=i+1; j<=n; j++){addedge(i+n,j,1,map[i][j]);//先到i点再到j点}addedge(0,i,1,map[0][i]);//0点到i点,容量为1,费用为最短路addedge(i,i+n,1,MINC);//拆点,cost值设为适当小的值,以免导致s->0->taddedge(i+n,t,1,map[0][i]);//i点到0点,容量为1,费用为最短路}printf("%d\n",minCostMaxflow(s,t)-MINC*n);}return 0;
}

HDU 4411 Arrest 费用流相关推荐

  1. hdu 4411 Arrest 费用流模板

    题意:警察局在0点,里面有k个警察,要将1-n的贼窝一网打尽,这1+n个点都有距离,且要求抓 i 点的贼前保证已经抓光 比i小的贼.警察们最后要回到0点,问满足抓到所以的贼(题目保证可行)最少走的路之 ...

  2. 【HDU】4411 Arrest 费用流

    传送门:[HDU]4411 Arrest 题目分析:题目的意思一开始没看懂= =...题意大致为:派出至多K个警队遵守先灭小的再灭老的的原则将N个城市的帮派全端了(要灭编号大的必须要先灭编号小的).且 ...

  3. hdu4411 Arrest(费用流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4411 [题意]给定N+1个点,距离,K个人,问,每人从0开始按照升序访问节点然后回到0,每个节点被访问 ...

  4. HDU 4411 Arrest(费用流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4411 题意:有n+1个城市,编号0到n.其中警察局在0号城市,1到n号城市中每个城市都有一个小偷.现在 ...

  5. hdu 4322 最大费用流

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4322 #include <cstdio> #include <cstring> ...

  6. HDU 4411 Arrest

    http://www.cnblogs.com/jianglangcaijin/archive/2012/09/24/2700509.html 思路: S->0 流量为K费用0 0->i 流 ...

  7. HDU 4411 Arrest 最小费用流

    题意:有N+1个顶点M条边的无向图.编号为0的顶点是警察厅.编号为1~N的顶点都有犯罪团伙.现在警察厅需要派出K支小队抓住这些犯罪团伙,第i个点的犯罪团伙被抓到之后会马上通知第i-1个犯罪团伙.现要求 ...

  8. hdu 4411 Arrest【最小费用流】

    题目链接 题意: 给定一个有(n+1)个节点的边权图,其中警察局在0点,其他n个点各有一个黑手党,现在警察局派出k个警察去抓黑手党,并逮捕会警察局,一旦黑手党i被抓,他会向黑手党i-1报信,任务就会失 ...

  9. 网络流 最大流 最小割 费用流

    [腾讯文档]网络流初步 网络流初步 文章目录 网络流初步 一.网络流简介 1. 网络 2. 流 3. 再次理解网络流 二.常见题型(三种) 三.相关问题对应算法介绍 1.最大流 (1) FF算法 - ...

最新文章

  1. FastAI 2019课程学习笔记 lesson 2:自行获取数据并创建分类器
  2. Python 学习日记5
  3. HDU4622(后缀自动机)
  4. 本地索引和全局索引的适用场景
  5. websocket连接出现 HTTP Authentication failed; no valid credentials available
  6. 查看高通kernel用哪个dsti
  7. 小猪cms之怎样查询绑定的微网站模板
  8. 还敢乱写代码??腾讯 Code Review 规范出炉!
  9. 【小游戏】2D游戏你比划我来猜(unity和陀螺仪交互)
  10. 高创CDHD伺服驱动器调试软件ServoStudioSetup V2.18版本与技术资料
  11. matlab如何修改图例的颜色,在MATLAB图例中设置线条颜色?
  12. h3c交换机服务器无响应,华为(H3C)交换机版本升级遇到的问题总结
  13. 下载google code中源码的几个工具
  14. 用python暴力破解rar加密文件(经过测试)
  15. Android 学习笔记(6)之Lambda和注解
  16. Tensorflow移动端之如何将自己训练的MNIST模型加载到Android手机上
  17. 最新面试必看的 数据库 知识大总结
  18. LeetCode881. 救生艇
  19. Intellidea创建maven project遇到的问题
  20. Extract High-frequency Data via PC SAS

热门文章

  1. OpenCV 学习笔记(Watershed)
  2. Ubuntu 16.04 中文版安装基础入门教程
  3. 岭南师范学院专插本计算机,2019年岭南师范学院专插本招生专业
  4. wordpress创建_如何在WordPress中轻松创建工作申请表
  5. superIO在Linux下的设备,X86 Linux ITE SuperIO GPIO Control
  6. UVA11992(线段树)
  7. JAVA中同目录下定义类,以及对象的创建与使用,内存图的原理
  8. MySQL数据库(5)
  9. 蓝桥杯 基础练习 数列排序 Java
  10. 电厂时钟同步设备(卫星同步时钟)应用方案