zoukankan      html  css  js  c++  java
  • 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
    ", ans);
        return 0;
    }
    

      

    禁止诸如开发者知识库/布布扣/码迷/学步园/马开东等 copy 他人博文乃至博客的网站转载 ,用户转载请注明出处:https://www.cnblogs.com/xcysblog/
  • 相关阅读:
    POJ 1401 Factorial
    POJ 2407 Relatives(欧拉函数)
    POJ 1730 Perfect Pth Powers(唯一分解定理)
    POJ 2262 Goldbach's Conjecture(Eratosthenes筛法)
    POJ 2551 Ones
    POJ 1163 The Triangle
    POJ 3356 AGTC
    POJ 2192 Zipper
    POJ 1080 Human Gene Functions
    POJ 1159 Palindrome(最长公共子序列)
  • 原文地址:https://www.cnblogs.com/xcysblog/p/9584411.html
Copyright © 2011-2022 走看看