• HDU Problem 4514 湫湫系列故事——设计风景线 【并查集+树的直径】


    湫湫系列故事——设计风景线

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
    Total Submission(s): 4115    Accepted Submission(s): 725

    Problem Description
      随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好。
      现在已经勘探确定了n个位置可以用来建设,在它们之间也勘探确定了m条可以设计的路线以及他们的长度。请问是否能够建成环形的风景线?如果不能,风景线最长能够达到多少?
      其中,可以兴建的路线均是双向的,他们之间的长度均大于0。
     
    Input
      测试数据有多组,每组测试数据的第一行有两个数字n, m,其含义参见题目描述;
      接下去m行,每行3个数字u v w,分别代表这条线路的起点,终点和长度。

      [Technical Specification]
      1. n<=100000 
      2. m <= 1000000
      3. 1<= u, v <= n 
      4. w <= 1000
     
    Output
      对于每组测试数据,如果能够建成环形(并不需要连接上去全部的风景点),那么输出YES,否则输出最长的长度,每组数据输出一行。
     
    Sample Input
    3 3 1 2 1 2 3 1 3 1 1
     
    Sample Output
    YES
     
    Source
     
    Recommend
    liuyiding   |   We have carefully selected several similar problems for you:  5792 5791 5790 5789 5788 
     
    一开始无限次超时(其实已经预感到了),看了前辈的博客之后才知道每棵树只要判断一次就好,这样可降低时间的复杂度。

    #include <bits/stdc++.h>
    #define MAXN 100010
    using namespace std;
    struct node{
        int from, to, val, next;
    } edge[MAXN*2];
    bool vis[MAXN], flag, used[MAXN];
    int dist[MAXN], head[MAXN], edgenum, ans, s, n, m;
    void addEdge(int x, int y, int z) {
        edge[edgenum].from = x;
        edge[edgenum].to = y;
        edge[edgenum].val = z;
        edge[edgenum].next = head[x];
        head[x] = edgenum++;
    }
    void bfs(int x) {
        queue<int> que; ans = 0;
        memset(vis, false, sizeof(vis));
        memset(dist, 0, sizeof(dist));
        while (!que.empty()) que.pop();
        que.push(x); vis[x] = true;
        while (que.size()) {
            int a = que.front(); que.pop();
            //标记是否已经访问过这棵树
            used[a] = true;
            for (int i = head[a]; i != -1; i = edge[i].next) {
                int b = edge[i].to;
                if (!vis[b] && dist[b] < dist[a] + edge[i].val) {
                    dist[b] = dist[a] + edge[i].val;
                    if(ans < dist[b]) {
                        ans = dist[b]; s = b;
                    }
                    vis[b] = true; que.push(b);
                }
            }
        }
    }
    int par[MAXN];
    int Find(int x) {
        if (x == par[x]) return x;
        return par[x] = Find(par[x]);
    }
    void unite(int x, int y) {
        int fx = Find(x);
        int fy = Find(y);
        if (fx != fy) par[fy] = fx;
        else flag = true;
    }
    void init() {
        for (int i = 0; i <= n; i++) {
            par[i]= i;
        }
        memset(head, -1, sizeof(head));
        edgenum = 0;
    }
    int main() {
        int a, b, c, d;
        while (scanf("%d%d", &n, &m) != EOF) {
            init(); flag = false;
            memset(used, false, sizeof(used));
            for (int i = 0; i < m; i++) {
                scanf("%d%d%d", &a, &b, &c);
                if (flag) continue;
                unite(a, b); addEdge(a, b, c);
                addEdge(b, a, c); d = a;
            }
            int maxx = 0;
            if (flag) printf("YES
    ");
            else {
                for (int i = 1; i <= n; i++) {
                    //如果节点所在的树没被访问过
                    if (!used[i]&& par[i] == i) {
                        bfs(i), bfs(s);
                        maxx = max(maxx, ans);
                    }
                }
                printf("%d
    ", maxx);
            }
        }
        return 0;
    }

  • 相关阅读:
    GLSL 变量属性
    php读取大文件的方法
    php 3种常见设计模式
    php类自动装载、链式操作、魔术方法
    统计文件中关键词出现的次数
    python先序、中序、后序排序
    Nginx缓存、压缩配置
    Ninx虚拟主机的配置
    python爬虫代码
    Nginx在安装过程经常出现的问题
  • 原文地址:https://www.cnblogs.com/cniwoq/p/6770870.html
Copyright © 2020-2023  润新知