题意:
求路径不长于x经过最多不同结点的路径的结点数
思路:
代码:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int maxn = 550;
vector<int> g[maxn];
int d[maxn][maxn][2];
int n, son[maxn], cnt[maxn];
void dfs(int x) {
for(int i=1; i<=n; i++)
d[x][i][0] = d[x][i][1] = 0x3f3f3f3f;
d[x][1][0] = d[x][1][1] = 0;
son[x] = 1;
for(int i=0; i<g[x].size(); i+=2) {
int y = g[x][i];
int len = g[x][i+1];
dfs(y);
for(int j=son[x]; j>0; j--) {
for(int k=1; k<=son[y]; k++) {
d[x][j+k][1] = min(d[x][j][1]+d[y][k][1]+len*2, d[x][j+k][1]);//最终要回到x点所以都是返回的
d[x][j+k][0] = min(d[x][j+k][0], min((d[x][j][1]+d[y][k][0]+len), (d[x][j][0]+d[y][k][1]+2*len)));//从当前结点返回到x或从其他结点返回到x
}
}
son[x] += son[y];
}
}
int main() {
int cas = 1;
while(scanf("%d", &n) != EOF && n) {
for(int i=0; i<=n; i++) g[i].clear();
memset(cnt, 0, sizeof(cnt));
for(int i=0; i<=n; i++) g[i].clear();
int u, v, w;
for(int i=1; i<n; i++) {
scanf("%d%d%d", &u, &v, &w);
cnt[u]++;// look for root
g[v].push_back(u);
g[v].push_back(w);
}
int root = 0;
for(int i=1; i<n; i++)
if(!cnt[i]) root = i;
dfs(root);
int q, x;
scanf("%d", &q);
printf("Case %d:\n",cas++);
while(q--) {
scanf("%d", &x);
int ans = 1;
for(int i=1; i<=n; i++) {
if(d[root][i][0] <= x) ans = i;
}
printf("%d\n", ans);
}
}
return 0;
}