标签:
第一开始想成了DP。尼玛后来才发现只有N条边,那就简单了。。
从起点S遍历整棵树,从某点跳出来回到终点T,问最短路长度。然而从某点跳出时走过的路径是一个定值。。。。
长度为整棵树的边长和sum*2-d1[i]。。然后求这个值加上回学校的路长的最小值就好了
#include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include <cstring> #include <cmath> #include <queue> #define INF 2000100000 using namespace std; typedef long long ll; const int maxn = 1e5 + 5; ll d2[maxn]; ll d1[maxn]; int vis[maxn]; struct Edge { int to, len; } edge[maxn]; struct node { int id, d; }; vector<Edge> g[maxn]; void bfs(int s) { memset(vis, 0, sizeof(vis)); memset(d1, 0, sizeof(d1)); d1[s] = 0; vis[s] = 1; queue<node> que; que.push((node) { 0, 0 }); while(!que.empty()) { node x = que.front(); que.pop(); int p = x.id; for(int i = 0; i < g[p].size(); ++i) { Edge &e = g[p][i]; if(!vis[e.to]) { d1[e.to] = d1[p] + e.len; vis[e.to] = 1; que.push((node) { e.to, d1[e.to] }); } } } } int main() { //freopen("in", "r", stdin); int n; while(~scanf("%d", &n)) { for(int i = 0; i <= n; ++i) scanf("%I64d", d2 + i); int from, to, len; ll sum = 0; for(int i = 0; i < n; ++i) { scanf("%d%d%d", &from, &to, &len); g[from].push_back((Edge) { to, len }); g[to].push_back((Edge) { from, len }); sum += len; } sum *= 2; bfs(0); //for(int i = 0; i <= n; ++i) printf("%d ",d1[i]); //printf("\n"); ll mx = INF; for(int i = 0; i <= n; ++i) { mx = min(mx, sum - d1[i] + d2[i]); } cout << mx << endl; for(int i = 0; i <= n; ++i) g[i].clear(); } }
标签:
原文地址:http://www.cnblogs.com/Norlan/p/4777753.html