hdu 4411 Arrest【最小费用流】

题目链接

题意:

给定一个有(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

(5)第i个城市的出点到汇点t,容量为1,花费为dis[0][i]

固定流量为k,用最小费用流跑一遍,答案加上n*1000000。

代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#pragma comment(linker,"/STACK:1024000000,1024000000")
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define MAX_V 1005
typedef pair P;
struct edge
{
    int to,cap,cost,rev;
};
int V;
vector 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 ,greater

>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]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

 

你可能感兴趣的:(图论)