有个引理是从任何一条直径上求得的最小偏心距都相同
贪心的话,核肯定是越大越好的
然后我们在一条直径上枚举长度不超过s的一段路径,作为核,求一下偏心距,最后求出最小值即可
注意,是路径长度,长度!不是点的数量!
#include
#include
#include
#include
#include
using namespace std;
#define debug(x) cerr << #x << "=" << x << endl;
const int MAXN = 1000 + 10;
const int INF = 1<<30;
int n,m,s,tot,last[MAXN],pre[MAXN],d[MAXN],vis[MAXN],lf,lt,max1,max2,ecc=INF;
int chain[MAXN],sum,ch_vis[MAXN],temp,maxx,ew[MAXN],tes[MAXN];
queue <int> q1, q2;
struct Edge {
int u,v,w,to;
Edge(){}
Edge(int u, int v, int w, int to) : u(u), v(v), w(w), to(to) {}
}e[MAXN * 2];
inline void add(int u, int v, int w) {
e[++tot] = Edge(u,v,w,last[u]);
last[u] = tot;
}
void bfs1(int st) {
q1.push(st);
memset(vis,0,sizeof(vis));
memset(d,0,sizeof(d));
while(!q1.empty()) {
int h = q1.front();
q1.pop();
vis[h] = 1;
for(int i=last[h]; i; i=e[i].to) {
int v = e[i].v;
int w = e[i].w;
if(!vis[v]) {
d[v] = max(d[v], d[h] + w);
if(d[v] > max1) {
lf = v;
max1 = d[v];
}
q1.push(v);
}
}
}
}
void bfs2(int st) {
q2.push(st);
memset(vis,0,sizeof(vis));
memset(d,0,sizeof(d));
while(!q2.empty()) {
int h = q2.front();
q2.pop();
vis[h] = 1;
for(int i=last[h]; i; i=e[i].to) {
int v = e[i].v;
int w = e[i].w;
if(!vis[v]) {
pre[v] = h;
ew[v] = w;
d[v] = max(d[v], d[h] + w);
if(d[v] > max2) {
lt = v;
max2 = d[v];
}
q2.push(v);
}
}
}
}
void bfs(int st) {
q1.push(st);
temp = 0;
memset(vis,0,sizeof(vis));
memset(d,0,sizeof(d));
d[st] = 0;
while(!q1.empty()) {
int h = q1.front();
q1.pop();
vis[h] = 1;
for(int i=last[h]; i; i=e[i].to) {
int v = e[i].v;
int w = e[i].w;
if(!vis[v]) {
if(ch_vis[v]) d[v] = d[h];
else d[v] = max(d[v], d[h] + w);
if(d[v] > temp) {
lf = v;
temp = d[v];
}
q1.push(v);
}
}
}
}
int main() {
cin >> n >> s;
for(int i=1; iint x, y, w;
cin >> x >> y >> w;
add(x, y, w);
add(y, x, w);
}
bfs1(1);
bfs2(lf);
while(lt) {
chain[++sum] = lt;
lt = pre[lt];
}
if(s == 0) {
for(int i=1; i<=sum; i++) {
bfs(chain[i]);
ecc = min(ecc, temp);
}
printf("%d\n", ecc);
return 0;
}
for(int i=1; i<=sum; i++) {
memset(ch_vis,0,sizeof(ch_vis));
memset(tes,0,sizeof(tes));
int now = chain[i];
maxx = 0;
int tosum = 0;
int total = 0;
while(now && tosum <= s) {
tosum += ew[now];
ch_vis[now] = 1;
tes[++total] = now;
now = pre[now];
}
for(int i=1; i<=total; i++) {
bfs(tes[i]);
maxx = max(maxx, temp);
}
ecc = min(ecc, maxx);
if(!now) {
printf("%d\n", ecc);
return 0;
}
}
return 0;
}