题中说任意两个点之间只有唯一1条路径,意思就是这是个树~
概括一下,就是求min(c->a, c->b) + a->b 的最大值。
显然,让整体最大,那就让这两项最大即可,a->b的最大值显然就是树的直径,跑两遍bfs(最短路)就行。
至于第一项,枚举c,每一次求出a->c, b->c的两者之中最小值,然后求这些最小值的最大值就行了~~
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a) memset(a, 0, sizeof(a)) 15 typedef long long ll; 16 typedef double db; 17 const int INF = 0x3f3f3f3f; 18 const int eps = 1e-8; 19 const int maxn = 2e5 + 5; 20 inline ll read() 21 { 22 ll ans = 0; 23 char ch = getchar(), last = ' '; 24 while(!isdigit(ch)) {last = ch; ch = getchar();} 25 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 26 if(last == '-') ans = -ans; 27 return ans; 28 } 29 inline void write(ll x) 30 { 31 if(x < 0) x = -x, putchar('-'); 32 if(x >= 10) write(x / 10); 33 putchar(x % 10 + '0'); 34 } 35 36 int n, m; 37 vector<int> v[maxn]; 38 vector<ll> c[maxn]; 39 40 #define pr pair<int, int> 41 #define mp make_pair 42 bool in[maxn]; 43 ll disA[maxn], disB[maxn]; 44 int dijkstra(int s, ll* dis) 45 { 46 Mem(in); 47 for(int i = 1; i <= n; ++i) dis[i] = (ll)INF * (ll)INF; 48 dis[s] = 0; 49 priority_queue<pr, vector<pr>, greater<pr> > q; 50 q.push(mp(dis[s], s)); 51 while(!q.empty()) 52 { 53 int now = q.top().second; q.pop(); 54 if(in[now]) continue; 55 in[now] = 1; 56 for(int i = 0; i < (int)v[now].size(); ++i) 57 { 58 if(dis[v[now][i]] > dis[now] + c[now][i]) 59 { 60 dis[v[now][i]] = dis[now] + c[now][i]; 61 q.push(mp(dis[v[now][i]], v[now][i])); 62 } 63 } 64 } 65 ll Max = 0; int pos; 66 for(int i = 1; i <= n; ++i) if(dis[i] > Max) Max = dis[i], pos = i; 67 return pos; 68 } 69 70 int main() 71 { 72 n = read(); m = read(); 73 for(int i = 1; i <= m; ++i) 74 { 75 int x = read(), y = read(); ll co = read(); 76 v[x].push_back(y); c[x].push_back(co); 77 v[y].push_back(x); c[y].push_back(co); 78 } 79 int a = dijkstra(1, disA); 80 int b = dijkstra(a, disA); 81 dijkstra(b, disB); 82 ll Max = 0; 83 for(int i = 1; i <= n; ++i) 84 Max = max(Max, min(disA[i], disB[i])); 85 write(disA[b] + Max); enter; 86 return 0; 87 }
话说回来,我刚开始用bfs跪了三个点(不是TLE),改成dijkstra就过了,为啥咧……树上两点间路径既然是唯一的,那么只要有一个合理的遍历顺序就行了啊……求助各界大佬。