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/

浙公网安备 33010602011771号