HDU4289 Control —— 最小割、最大流 、拆点

题目链接:https://vjudge.net/problem/HDU-4289

 

Control

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3829    Accepted Submission(s): 1610


Problem Description
  You, the head of Department of Security, recently received a top-secret information that a group of terrorists is planning to transport some WMD 1 from one city (the source) to another one (the destination). You know their date, source and destination, and they are using the highway network.
  The highway network consists of bidirectional highways, connecting two distinct city. A vehicle can only enter/exit the highway network at cities only.
  You may locate some SA (special agents) in some selected cities, so that when the terrorists enter a city under observation (that is, SA is in this city), they would be caught immediately.
  It is possible to locate SA in all cities, but since controlling a city with SA may cost your department a certain amount of money, which might vary from city to city, and your budget might not be able to bear the full cost of controlling all cities, you must identify a set of cities, that:
  * all traffic of the terrorists must pass at least one city of the set.
  * sum of cost of controlling all cities in the set is minimal.
  You may assume that it is always possible to get from source of the terrorists to their destination.
------------------------------------------------------------
1 Weapon of Mass Destruction
 

 

Input
  There are several test cases.
  The first line of a single test case contains two integer N and M ( 2 <= N <= 200; 1 <= M <= 20000), the number of cities and the number of highways. Cities are numbered from 1 to N.
  The second line contains two integer S,D ( 1 <= S,D <= N), the number of the source and the number of the destination.
  The following N lines contains costs. Of these lines the ith one contains exactly one integer, the cost of locating SA in the ith city to put it under observation. You may assume that the cost is positive and not exceeding 107.
  The followingM lines tells you about highway network. Each of these lines contains two integers A and B, indicating a bidirectional highway between A and B.
  Please process until EOF (End Of File).
 

 

Output
  For each test case you should output exactly one line, containing one integer, the sum of cost of your selected set.
  See samples for detailed information.
 

 

Sample Input
5 6 5 3 5 2 3 4 12 1 5 5 4 2 3 2 4 4 3 2 1
 

 

Sample Output
3
 

 

Source
 

 

Recommend
liuyiding

 

 

题意:

有n个城市,m条路(无向),一些恐怖分子准备从S城市出发,运送一些大规模杀伤性武器到城市D。于是警察准备在一些城市作部署,以防止大规模杀伤性武器能够到达目的地,即把城市S和城市D割裂开,且部署每一个城市都有其特定的花费。问:怎样用最少的花费来完成任务?

 

题解:

可知为求权值和最小的割点集,但是又不能用Tarjan算法去做。所以可以适当变形:把每个城市拆成两个点u和u',u和u'之间连一条有有向边:u-->u',且权值为部署这个城市所需要的花费。这样,就把问题转化为求最小割了,求最小割又可以转化为求最大流。以下是具体建图:

1.把每个城市拆成两个点u和u',u和u'之间连一条有有向边:u-->u',且权值为部署这个城市所需要的花费。

2.对于每个相邻的城市,连上一条无向边,且权值为INF。

 

 

代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <cmath>
 7 #include <queue>
 8 #include <stack>
 9 #include <map>
10 #include <string>
11 #include <set>
12 using namespace std;
13 typedef long long LL;
14 const int INF = 2e9;
15 const LL LNF = 9e18;
16 const int mod = 1e9+7;
17 const int MAXN = 4e2+10;
18 
19 int maze[MAXN][MAXN];
20 int gap[MAXN], dis[MAXN], pre[MAXN], cur[MAXN];
21 int flow[MAXN][MAXN];
22 
23 int sap(int start, int end, int nodenum)
24 {
25     memset(cur, 0, sizeof(cur));
26     memset(dis, 0, sizeof(dis));
27     memset(gap, 0, sizeof(gap));
28     memset(flow, 0, sizeof(flow));
29     int u = pre[start] = start, maxflow = 0, aug = INF;
30     gap[0] = nodenum;
31 
32     while(dis[start]<nodenum)
33     {
34         loop:
35         for(int v = cur[u]; v<nodenum; v++)
36         if(maze[u][v]-flow[u][v]>0 && dis[u] == dis[v]+1)
37         {
38             aug = min(aug, maze[u][v]-flow[u][v]);
39             pre[v] = u;
40             u = cur[u] = v;
41             if(v==end)
42             {
43                 maxflow += aug;
44                 for(u = pre[u]; v!=start; v = u, u = pre[u])
45                 {
46                     flow[u][v] += aug;
47                     flow[v][u] -= aug;
48                 }
49                 aug = INF;
50             }
51             goto loop;
52         }
53 
54         int mindis = nodenum-1;
55         for(int v = 0; v<nodenum; v++)
56             if(maze[u][v]-flow[u][v]>0 && mindis>dis[v])
57             {
58                 cur[u] = v;
59                 mindis = dis[v];
60             }
61         if((--gap[dis[u]])==0) break;
62         gap[dis[u]=mindis+1]++;
63         u = pre[u];
64     }
65     return maxflow;
66 }
67 
68 int main()
69 {
70     int n, m, start, end;
71     while(scanf("%d%d", &n,&m)!=EOF)
72     {
73         scanf("%d%d", &start, &end);
74         start = start-1; end = n+end-1;
75         memset(maze, 0, sizeof(maze));
76         for(int i = 0; i<n; i++)
77         {
78             int cost;
79             scanf("%d", &cost);
80             maze[i][n+i] = cost;
81         }
82         for(int i = 0; i<m; i++)
83         {
84             int u, v;
85             scanf("%d%d", &u, &v);
86             u--; v--;
87             maze[n+u][v] = INF;
88             maze[n+v][u] = INF;
89         }
90 
91         cout<< sap(start, end, 2*n) <<endl;
92     }
93 }
View Code

 

posted on 2017-12-22 12:48  h_z_cong  阅读(263)  评论(0编辑  收藏  举报

导航