BZOJ1297: [SCOI2009]迷路
看上去有点据称的意思,感觉这边权不太会搞啊
发现边权范围∈[1, 9]
其实可以拆点,一个点拆成九个点
一条从 i 到 j 的长为 k 路径就是从 i 的第 k 个点连向 j 的第一个点
答案就是 1 的第一个点到 n 的第一个点的方案数
矩乘一波就好了
代码:
#include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cctype> #include<queue> using namespace std; const int MAXN = 500005; struct EDGE{ int nxt, to, val; EDGE(int NXT = 0, int TO = 0, int VAL = 0) {nxt = NXT; to = TO; val = VAL;} }edge[MAXN << 1]; int n, s, totedge, mxpt, p, q, top, lmt, ans = 0x7fffffff; int head[MAXN], dst[MAXN], frm[MAXN]; pair<int,int> stk[MAXN]; bool ind[MAXN]; queue<int> que; inline int rd() { register int x = 0; register char c = getchar(); while(!isdigit(c)) c = getchar(); while(isdigit(c)) { x = x * 10 + (c ^ 48); c = getchar(); } return x; } inline void add(int x, int y, int v) { edge[++totedge] = EDGE(head[x], y, v); head[x] = totedge; return; } inline void bfs(int bgn) { for(int i = 1; i <= n; ++i) dst[i] = 0x7fffffff; dst[bgn] = 0; que.push(bgn); while(!que.empty()) { int x = que.front(); que.pop(); if(dst[x] > dst[mxpt]) mxpt = x; for(int i = head[x]; i; i = edge[i].nxt) if(dst[edge[i].to] == 0x7fffffff) { int y = edge[i].to; frm[y] = x; if(ind[y]) dst[y] = dst[x]; else dst[y] = dst[x] + edge[i].val; que.push(y); } } return; } void dfs(int x, int fa) { dst[x] = 0; for(int i = head[x]; i; i = edge[i].nxt) if(edge[i].to != fa) { int y = edge[i].to; dfs(y, x); if(ind[y]) dst[x] = max(dst[x], dst[y]); else dst[x] = max(dst[x], dst[y] + edge[i].val); } return; } int main() { n = rd(); s = rd(); register int xx, yy, vv; for(int i = 1; i < n; ++i) { xx = rd(); yy = rd(); vv = rd(); add(xx, yy, vv); add(yy, xx, vv); } bfs(1); p = mxpt; mxpt = 0; bfs(p); q = mxpt; stk[++top] = make_pair(mxpt, dst[mxpt]); ind[mxpt] = true; while(mxpt != p) { mxpt = frm[mxpt]; stk[++top] = make_pair(mxpt, dst[mxpt]); ind[mxpt] = true; } dfs(p, 0); for(int i = 1; i <= top; ++i) lmt = max(lmt, dst[stk[i].first]); int lptr, rptr = 0, cur; for(lptr = 1; lptr <= top; ++lptr) { cur = lmt; while(stk[lptr].second - stk[rptr + 1].second <= s && rptr + 1 <= top) ++rptr; cur = max(cur, max(stk[1].second - stk[lptr].second, stk[rptr].second)); ans = min(ans, cur); } printf("%d\n", ans); return 0; }
禁止诸如开发者知识库/布布扣/码迷/学步园/马开东等 copy 他人博文乃至博客的网站转载
,用户转载请注明出处:https://www.cnblogs.com/xcysblog/