2014-12-20 22:30:18
总结:做了两道...慢成狗,降了一点orz....
A:水题...莫名其妙wa一发。。。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <iostream> 11 #include <algorithm> 12 using namespace std; 13 #define lp (p << 1) 14 #define rp (p << 1|1) 15 #define getmid(l,r) (l + (r - l) / 2) 16 #define MP(a,b) make_pair(a,b) 17 typedef long long ll; 18 typedef unsigned long long ull; 19 const int INF = 1 << 28; 20 const int maxn = 4010; 21 22 int T,K,n; 23 int first[maxn],next[maxn],ver[maxn],w[maxn],ecnt; 24 ll dp[maxn][60]; 25 ll siz[maxn]; 26 27 void Init(){ 28 fill(dp[0],dp[0] + maxn * 60,INF); 29 memset(first,-1,sizeof(first)); 30 ecnt = 0; 31 } 32 33 void Add_edge(int u,int v,int fee){ 34 next[++ecnt] = first[u]; 35 ver[ecnt] = v; 36 w[ecnt] = fee; 37 first[u] = ecnt; 38 } 39 40 void Dfs(int p,int fa){ 41 siz[p] = 1; 42 dp[p][1] = dp[p][0] = 0; 43 for(int i = first[p]; i != -1; i = next[i]){ 44 int v = ver[i]; 45 if(v == fa) continue; 46 Dfs(v,p); 47 siz[p] += siz[v]; 48 for(int m = min(siz[p],(ll)K); m >= 0; --m){ 49 for(int j = 0; j <= m; ++j){ 50 dp[p][m] = min(dp[p][m],dp[p][m - j] + dp[v][j] + (ll)j * (K - j) * w[i]); 51 } 52 } 53 } 54 } 55 56 int main(){ 57 int a,b,c; 58 scanf("%d",&T); 59 while(T--){ 60 Init(); 61 scanf("%d%d",&n,&K); 62 for(int i = 1; i < n; ++i){ 63 scanf("%d%d%d",&a,&b,&c); 64 Add_edge(a,b,c); 65 Add_edge(b,a,c); 66 } 67 Dfs(1,0); 68 printf("%I64d\n",dp[1][K] * 2); 69 } 70 return 0; 71 }