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:
[Cpp]
# Include <iostream>
# Include <algorithm>
# Include <cstdio>
# Include <cstdlib>
# Include <cstring>
# Include <queue>
# Include <math. h>
# Include <climits>
# Define maxn105
# Define INF 1000
Using namespace std;
Int map [MAXN] [MAXN], w [MAXN], v [MAXN], used [MAXN], dp [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 problem of parity of 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; // 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) // all the points that can be reached are not half of the total and are 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;
}