zoukankan      html  css  js  c++  java
  • 【洛谷 P3304】[SDOI2013]直径(树的直径)

    题目链接
    题意,求一棵树被所有直径经过的边的条数。
    这题是我们8.25KS图论的最后一题,当时我果断打了暴力求所有直径然后树上差分统计的方法,好像有点小问题,boom0了。
    考完改这题,改了好久,各种各样的小bug,至少有七八个。。。
    思路:先随便找一条直径,然后从一个端点开始遍历这条直径,如果当前点能分叉出一条直径,那么这条直径后面的点都不可能被所有直径穿过了,于是我们找到第一个能分叉的点,然后再从这个点往回遍历,找到第一个能分叉的点,这2个点中间的路径的边即为所求。
    代码就算了吧,打这题时我就没想过要有可读性

    #include <cstdio>
    #include <algorithm>
    #include <queue>
    using namespace std;
    #define INF 2147483647
    #define Open(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout);
    #define Close fclose(stdin); fclose(stdout);
    const int MAXN = 200010;
    inline int read(){
    	int s = 0, w = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); }
    	while(ch >= '0' && ch <= '9') { s = s * 10 + ch - '0'; ch = getchar(); }
    	return s * w;
    }
    struct Edge{
    	int next, to, dis;
    }e[MAXN << 1];
    int num, head[MAXN], flag[MAXN];
    inline void Add(int from, int to, int dis){
    	e[++num] = (Edge){ head[from], to, dis };
    	head[from] = num;
    }
    int pre[MAXN], in[MAXN];
    int n, ans, Maxu, ans1;
    long long Max;
    void dfs(int u, int fa, long long dep){
        if(dep > Max) Max = dep, Maxu = u;
    	for(int i = head[u]; i; i = e[i].next)
    	   if(e[i].to != fa)
    	     dfs(e[i].to, u, dep + e[i].dis);
    }
    void DFS(int u, int fa, long long dep){
        pre[u] = fa;
        if(dep > Max) Max = dep, Maxu = u;
    	for(int i = head[u]; i; i = e[i].next)
    	   if(e[i].to != fa)
    	     DFS(e[i].to, u, dep + e[i].dis);
    }
    bool existOther(int u, int fa, long long dep){
        if(dep == Max) return true;
        for(int i = head[u]; i; i = e[i].next)
           if(e[i].to != fa)
             if(existOther(e[i].to, u, dep + e[i].dis)) return true;
        return false;
    }
    int A, B, C;
    int main(){
        Open("diameter");
    	n = read();
    	for(int i = 1; i < n; ++i){
    	   A = read(); B = read(); C = read();
    	   Add(A, B, C); Add(B, A, C);
    	}
    	Max = -1; dfs(1, 0, 0);
    	Max = -1; DFS(Maxu, 0, 0);
    	int now = Maxu, o = 0, fa = 0, Plus = 0;
    	long long deep = 0;
    	while(now) flag[now] = 1, now = pre[now];
    	for(int i = 1; i <= n; ++i) if(!flag[i]) pre[i] = 0;
    	now = Maxu;
    	while(now){
          Plus = 0;
          for(int i = head[now]; i; i = e[i].next)
             if(e[i].to != pre[now] && e[i].to != fa){
               if(existOther(e[i].to, now, deep + e[i].dis)){
                 o = now;
                 break;
               }
             }
             else if(e[i].to == pre[now]) Plus = e[i].dis;
          if(!o && !pre[now]) o = now;
          if(o) break;
          fa = now;
          now = pre[now];
          deep += Plus;
        }                           //找到第一个分叉的点
            ans = 0;       //往回遍历
            now = o;
            fa = pre[now];
            deep = Max - deep;
            while(now != Maxu){
              int nxt;
              ++ans;
              for(int i = head[now]; i; i = e[i].next)
                 if(pre[e[i].to] != now && e[i].to != fa){
                   if(existOther(e[i].to, now, deep + e[i].dis)){
                     printf("%I64d
    %d
    ", Max, ans - 1);
                     //system("pause");
                     return 0;
                   }
                 }
                 else if(pre[e[i].to] == now) nxt = e[i].to, Plus = e[i].dis;
              fa = now;
              now = nxt;
              deep += Plus;
            }
        printf("%I64d
    %d
    ", Max, ans);  //如果都不能分叉
    	Close;
    	//system("pause");
    	return 0;
    }
    
    
  • 相关阅读:
    Serialize and Deserialize Binary Tree
    sliding window substring problem汇总贴
    10. Regular Expression Matching
    《深入理解计算机系统》(CSAPP)读书笔记 —— 第七章 链接
    程序员如何写一份合格的简历?(附简历模版)
    9个提高代码运行效率的小技巧你知道几个?
    《深入理解计算机系统》(CSAPP)读书笔记 —— 第六章 存储器层次结构
    24张图7000字详解计算机中的高速缓存
    《深入理解计算机系统》(CSAPP)实验四 —— Attack Lab
    《深入理解计算机系统》(CSAPP)读书笔记 —— 第五章 优化程序性能
  • 原文地址:https://www.cnblogs.com/Qihoo360/p/9541297.html
Copyright © 2011-2022 走看看