Question link: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 3339
I was a little interested when I saw a topic with the shortest path and a backpack when I looked at graph 500 at night. So I spent more than an hour on this topic.
It takes half of the power to detonate a nuclear bomb if terrorists want to bomb the earth. Electricity is distributed in different power stations. Each power station has different power supplies. The purpose is to dispatch tanks, destroy power stations, and prevent them from being detonated.
An undirected graph is given, and the minimum total distance is required to destroy more than half of the electricity. Note that a tank is required for each power station.
Each power station has its own cost (0 to its shortest circuit) and value (power ). Therefore, it is converted to a problem where the minimum cost is more than half of the power consumption. Pay attention to the details of this question.
AC code:
# Include <iostream> # include <algorithm> # include <cstdio> # include <cstdlib> # include <cstring> # include <queue> # include <math. h >#include <climits> # define maxn 105 # define INF 1000 using namespace STD; int map [maxn] [maxn], W [maxn], V [maxn], used [maxn], DP [1, 505005]; int max (int A, int B) {return A> B? A: B;} int main () {// freopen ("in.txt", "r", stdin); int I, j, n, m, T, A, B, c, TOPV, f = 0; scanf ("% d", & T); While (t --) {scanf ("% d", & N, & M); for (I = 0; I <= N; I ++) {for (j = 0; j <= N; j ++) map [I] [J] = 1000; Map [I] [I] = 0;} for (I = 0; I <m; I ++) {scanf ("% d", & A, & B, & C); If (C <map [a] [B]) map [a] [B] = map [B] [a] = C; // pay attention to the duplicate edge} TOPV = 0; for (I = 1; I <= N; I ++) {scanf ("% d", & V [I]); TOPV + = V [I];} f = TOPV % 2; // pay attention to the parity of the total power consumption! TOPV = (TOPV + 1)/2; for (I = 0; I <= N; I ++) W [I] = map [0] [I]; memset (used, 0, sizeof (used); used [0] = 1; int sum = 0, sumv = 0; For (INT u = 0; U <N; U ++) {int mini = 1000, K = 0; for (I = 1; I <= N; I ++) if (! Used [I] & Mini> W [I]) {mini = W [I]; k = I;} If (k = 0) break; // if the path cannot be found, exit used [k] = 1; sum + = W [k]; sumv + = V [k]; for (I = 1; I <= N; I ++) if (! Used [I] & W [I]> W [k] + map [k] [I]) {W [I] = W [k] + map [k] [I] ;}} if (sumv + F <= TOPV) // not half of all points that can be reached, output. {Printf ("impossible \ n"); continue;} memset (DP, 0, sizeof (DP); for (I = 1; I <= N; I ++) {for (j = sum; j> = W [I]; j --) {DP [J] = max (DP [J], DP [J-W [I] + V [I]) ;}} int ans = 0; for (I = 0; I <= sum; I ++) if (DP [I] + F> TOPV) {ans = I; break;} printf ("% d \ n", ANS);} return 0 ;}