zoukankan      html  css  js  c++  java
  • 树网的核 NOIP 2007 luogu P1099

    AC传送门

    看到这个N值,直接就想到暴力。

    直接O(N3)的暴力即可。

    PS:  先找到树的直径,并记录直径上的点(直接搜索时记录所有的点的father即可)。然后枚举符合要求的直径上的段落,直接DFS暴搜。

    虽然思路简单,但细节和代码实现还是要有一点操作(特别是程序设计上)

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define N 100010
    #define isdigit(c) ((c)>='0'&&(c)<='9')
    
    int read(){
        int x = 0, s = 1;
        char c = getchar();
        while(!isdigit(c)){
            if(c == '-')s = -1;
            c = getchar();
        }
        while(isdigit(c)){
            x = (x << 1) + (x << 3) + (c ^ '0');
            c = getchar();
        }
        return x * s;
    }
    
    struct node{
        int v, w, next;
    } t[N << 1];
    int f[N];
    int n, s;
    int fa[N], next_dis[N];
    int dis[N], dist[N];
    bool vis[N];
    int ans2 = -66666, ans = (int)8e9;  /*don't forget the original value*/
    
    int bian = 0;
    inline void add(int u, int v, int w){
        t[++bian] = (node){v, w, f[u]}, f[u] = bian; /*both dire need to be added*/
        t[++bian] = (node){u, w, f[v]}, f[v] = bian;
        return ;
    }
    
    int max_dis = -233333, cur, s1, s2;
    void dfs1(int now, int father, int dis){
        if(dis > max_dis){
            cur = now;
            max_dis = dis;
        }
        for(int i = f[now]; i; i = t[i].next){
            int v = t[i].v, w = t[i].w;
            if(v != father && !vis[v]){
                fa[v] = now;
                dist[v] = dist[now] + w;  /*dist is the distance of the two points*/
                dfs1(v, now, dis + w);    
            }
        }
        return ;
    }
    
    inline void search(int x, int& s){ /*find the farthest point of x, and record it as s*/
        max_dis = -23333;
        dist[x] = 0;
        dfs1(x, x, 0);
        s = cur;
        return ;
    }
    
    void dfs2(int now, int father){
        for(int i = f[now]; i; i = t[i].next){
            int v = t[i].v, w = t[i].w;
            if(v != father && !vis[v]){
                vis[v] = 1;
                dis[v] = dis[now] + w;
                ans2 = max(ans2, dis[v]); /*record the max distance */
                dfs2(v, now);
            }
        }
        return ;
    }
    
    int main(){
    //    freopen("hh.txt", "r", stdin);s
        n = read(), s = read();
        for(int i = 1;i < n; i++){
            int x = read(), y = read(), w = read();
            add(x, y, w);
        }
        search(1, s1);
        memset(fa, 0, sizeof(fa)); /*remember to clean the fa, as this time it is wrong*/
        search(s1, s2);
        for(int i = s2; i; i = fa[i]){
            for(int j = i; j; j = fa[j]){
                if(dist[i] - dist[j] <= s){
                    memset(vis, 0, sizeof(vis));
                    ans2 = -666;
                    for(int k = i; k != j; k = fa[k])
                        vis[k] = 1;
                    vis[j] = 1;  /*don't miss j!*/
                    for(int k = i;k != j; k = fa[k]){
                        dis[k] = 0;
                        dfs2(k, k);
                    }
                    dis[j] = 0;
                    dfs2(j, j); 
                    ans = min(ans, ans2);
                }
                else break;
            }
        }
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    mysql 函数 存储过程 事件(event) job 模板
    protobuf 无proto 解码 decode 语言 java python
    mitmproxy fiddler 抓包 填坑
    android adb 常用命令
    android机器人 模拟 踩坑过程
    RabbitMQ添加新用户并支持远程访问
    Windows下RabbitMQ安装及配置
    Java mybatis mysql 常用数据类型对应关系
    easyExcel 踩坑
    linux防火墙查看状态firewall、iptable
  • 原文地址:https://www.cnblogs.com/wondering-world/p/13050010.html
Copyright © 2011-2022 走看看