Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 4289
The question is that some terrorists want to go from s city to D city. They want to arrange special agents in some cities to ensure that they will be able to seize the terrorists, because it will take a certain amount of money to arrange special agents, therefore, we hope to find the minimum cost.
Idea: You can split each city, that is, each vertex, into an incoming vertex and an outgoing vertex. For example, X points are divided into X and x + N, the Edge Weight of the Two-point connection is the cost of Agent arrangement on the X point. If there is a link between x and y, connect x + N, y, and find the maximum flow from S to D. The reason for this is that the traffic updated each time is the smallest of all edges in the Process of maximizing the flow. In this way, the edge of the smallest traffic is the line between two points split at each vertex, in this process, the maximum flow is limited by the cost of all points.
1/* calculate the maximum stream using the dinic algorithm */2 # include <stdio. h> 3 # include <string. h> 4 # include <iostream> 5 # define point_max 10000 6 # define edge_max 100000 7 # define inf_max 999999999 8 using namespace STD; 9 struct edge 10 {11 int; /* points */12 INT next;/* points to the next adjacent edge */13 int W;/* weight */14} edge [edge_max]; 15 int Len; /* Number of edges */16 int point [point_max]; 17 int vertex, edge; 18 int d [point_max]; 19 void Init () /* initialize */20 {21 Len = 0; 22 memset (point, 0, sizeof (point); 23} 24 int add_edge (int A, int B, int W) /* add an edge with the weight from A to B w */25 {26 Len ++; 27 edge [Len]. W = W; 28 edge [Len]. to = B; 29 edge [Len]. next = point [a]; 30 point [a] = Len; 31 return 0;/* No duplicate edge, insert */32} 33 int BFS (int s) 34 {35 int Q [point_max], front = 0, rear = 1, J, T, I; 36 Q [0] = s; 37 memset (D,-1, sizeof (d);/**/38 D [s] = 0; 39 while (front <rear) 40 {41 t = Q [Front ++]; 42 for (j = point [T]; J; j = edge [J]. next) 43 {44 If (d [edge [J]. to] =-1 & edge [J]. w> 0) 45 {46 d [edge [J]. to] = d [T] + 1; 47 Q [rear ++] = edge [J]. to;/* layer by layer */48} 49} 50} 51 if (d [vertex]> = 0) 52 return 1; 53 return 0; 54} 55 long min (long a, long B) 56 {57 Return a <B? A: B; 58} 59 long dinic (int t, long sum)/* search for augmented path */60 {61 int I, OS, J; 62 long; 63 If (t = vertex)/* If the vertex has been found, return sum */64 return sum; 65 OS = sum; 66 for (I = point [T]; I & sum; I = edge [I]. next) 67 {68 if (d [edge [I]. to] = d [T] + 1 & edge [I]. w> 0)/* feasible stream, that is, augmented path */69 {70 A = dinic (edge [I]. to, min (sum, edge [I]. w); 71 edge [I]. w-= A; 72 for (j = point [edge [I]. to]; edge [J]. to! = T; j = edge [J]. next); 73 edge [J]. W + = A;/* Process Reverse edges */74 sum-= A; 75} 76} 77 return OS-sum; 78} 79 long dinic (INT S) /* dinic algorithm */80 {81 long ans = 0; 82 while (BFS (s)/* traverses the entire graph, determine whether the maximum stream */83 ans + = dinic (S, inf_max) has been completed;/* Add the traffic that can be increased */84 return ans; 85} 86 87 int main () 88 {89 int I, j, X, Y, W, S, D; 90 int cost [205]; 91 while (scanf ("% d", & vertex, & edge )! = EOF) 92 {93 Init (); 94 memset (cost, 0, sizeof (cost); 95 scanf ("% d", & S, & D ); 96 for (I = 1; I <= vertex; I ++) 97 {98 scanf ("% d", & cost [I]); 99 add_edge (I, I + vertex, cost [I]); 100 add_edge (I + vertex, I, 0); 101} 102 for (I = 0; I <edge; I ++) 103 {104 scanf ("% d", & X, & Y); 105 add_edge (x + vertex, Y, inf_max); 106 add_edge (Y, x + vertex, 0); 107 add_edge (Y + vertex, X, inf_max);/* Add reverse edges */108 add_edge (X, Y + vertex, 0 ); 109} 110 vertex = d + vertex; 111 // cout <"=" <Endl; 112 printf ("% LLD \ n", dinic (s )); /* use s as the Source Vertex, and vertex as the sink vertex */113} 114 return 0; 115}View code