zoukankan      html  css  js  c++  java
  • POJ-2114 Boatherds

    题面

    太长了不放了

    链接:https://vjudge.net/problem/POJ-2114

    题意

    给定一颗树,m次询问,每次询问是否有路径长度为k的树

    题解

    和上题差不多,我们可以顺便把路径长度等于k的路径有多少条也算出来,大于0就有,等于0就没有

    方法也是和上题一样,这题可以先合并长度相等的路径,然后two pointer扫一遍

    代码

    #include <cstdio>
    #include <algorithm>
    #include <vector>
    using namespace std;
    const int N = 1e5 + 50;
    typedef long long ll;
    const int inf = 0x3f3f3f3f;
    struct node {
        int v; ll w;
        node(int v = 0, ll w = 0): v(v), w(w) {}
    };
    struct D {
        ll val, len;
    } a[N * 10];
    vector<node> G[N];
    int sze[N];
    int msze[N];
    int S;
    int root;
    int maxx;
    int vis[N];
    void getroot(int u, int f) {
        sze[u] = 1;
        msze[u] = 0;
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i].v;
            if (v == f || vis[v]) continue;
            getroot(v, u);
            sze[u] += sze[v];
            msze[u] = max(msze[u], sze[v]);
        }
        msze[u] = max(msze[u], S - sze[u]);
        if (maxx > msze[u]) {
            root = u;
            maxx = msze[u];
        }
    }
    int dis[N * 10];
    int cnt = 0;
    void getdis(int u, int f, int d) {
        dis[++cnt] = d;
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i].v;
            if (v == f || vis[v]) continue;
            getdis(v, u, d + G[u][i].w);
        }
    }
    ll k;
    ll calc(int u, ll w) {
        cnt = 0;
        getdis(u, 0, w);
        sort(dis + 1, dis + cnt + 1);
        int num = 0;
        dis[0] = -1;//这里注意,要不第一个dis[1]为0时会出现错误
        for (int i = 1; i <= cnt; i++) {
            if (dis[i] != dis[i - 1]) {
                a[++num].val = dis[i];
                a[num].len = 1;
            }
            else a[num].len++;
        }
        ll ans = 0;
        int l = 1, r = num;
        while (l <= r) {
            if (a[l].val + a[r].val == k) {
                if (l == r) {
                    ans += a[l].len * (a[l].len - 1) / 2;
                    return ans;
                }
                ans += a[l].len * a[r].len;
                l++, r--;
            }
            else if (a[l].val + a[r].val < k) l++;
            else r--;
        }
        return ans;
    }
    ll ans;
    void dfs(int u) {
        ans += calc(u, 0);
        vis[u] = 1;
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i].v;
            if (vis[v]) continue;
            ans -= calc(v, G[u][i].w);
            S = sze[v];
            root = 0;
            maxx = inf;
            getroot(v, 0);
            dfs(root);
        }
    }
    int main() {
        int n;
        while (scanf("%d", &n) && n) {
            for (int i = 1; i <= n; i++) G[i].clear();
            for (int i = 1; i <= n; i++) {
                int v;
                while (scanf("%d", &v) && v) {
                    ll w;
                    scanf("%lld", &w);
                    G[i].push_back(node(v, w));
                    G[v].push_back(node(i, w));
                }
            }
            while (scanf("%lld", &k) && k) {
                for (int i = 1; i <= n; i++) {
                    vis[i] = 0;
                    sze[i] = 0;
                    msze[i] = 0;
                    cnt = 0;
                }
                S = n;
                root = 0;
                maxx = inf;
                getroot(1, 0);
                ans = 0;
                dfs(root);
                if (ans > 0) puts("AYE");
                else puts("NAY");
            }
            puts(".");
        }
        return 0;
    }
    

    这题re两发,不是因为数组开小,也不是因为别的什么,而是把(G[u][i].v)写成(G[u][i].w)

  • 相关阅读:
    extern--C#调用C++等其他非托管代码
    unhandledException详细介绍
    MySql如何安装?
    Mindoc搭建流程
    反射_IsDefined判断方法上有自定义的标签
    WebApi_返回Post格式数据
    编码
    IP地址与MAC地址
    Tcp/Ip:Telnet指令
    create-react-app使用的问题
  • 原文地址:https://www.cnblogs.com/artoriax/p/12206513.html
Copyright © 2011-2022 走看看