• HDU


    题目:

    随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好。 
    现在已经勘探确定了n个位置可以用来建设,在它们之间也勘探确定了m条可以设计的路线以及他们的长度。请问是否能够建成环形的风景线?如果不能,风景线最长能够达到多少? 
    其中,可以兴建的路线均是双向的,他们之间的长度均大于0。

    思路:

    将给出的边的两个端点用并查集放在一起,如果这两个点的祖先相等说明构成了一个环。

    在这个用并查集连成的连通分量里边,找到他的root(fa[i] = i),然后先用一个BFS找到他的端点,然后从这个端点开始找树上的最长距离。

    代码:

    #include <bits/stdc++.h>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <queue>
    #define MAX 1000000000
    #define inf 0x3f3f3f3f
    #define FRE() freopen("in.txt","r",stdin)
    
    using namespace std;
    typedef unsigned long long ll;
    const int maxn = 100005;
    int n,m;
    struct Edge
    {
        int to,w;
    };
    vector<Edge> mp[maxn];
    int fa[maxn],vis[maxn],d[maxn];
    
    int _find(int x)
    {
        return fa[x] == x ? x : fa[x] = _find(fa[x]);
    }
    
    bool judgeLoop(int u,int v)
    {
        int x = _find(u);
        int y = _find(v);
        if(x!=y)
        {
            fa[x] = y;
            return false;
        }
        return true;//x==y说明两者已经在一个连通分量里边了,也就是有环了
    }
    
    int BFS(int s)//两个作用1.查找最远的结点2.计算最长的距离
    {
        memset(vis,0,sizeof(vis));
        memset(d,0,sizeof(d));
        vis[s] = 1;
        queue<int> que;
        que.push(s);
        int ed = s,mmax=0;
        while(!que.empty())
        {
            int u = que.front();
            que.pop();
            for(int i=0; i<mp[u].size(); i++)
            {
                Edge e = mp[u][i];
                if(vis[e.to] == 0)
                {
                    d[e.to] = d[u]+e.w;//获取从根节点到e.to结点的距离
                    vis[e.to] = 1;
                    que.push(e.to);
                    if(d[e.to]>mmax)//找到这棵树的距离根节点最远的结点
                    {
                        ed = e.to;
                        mmax = d[e.to];
                    }
                }
            }
        }
        return ed;
    }
    
    int main()
    {
        //FRE();
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            for(int i=0; i<maxn; i++) { fa[i] = i; mp[i].clear();}
            bool ok = false;
            for(int i=0; i<m; i++)
            {
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                mp[u].push_back(Edge{v,w});
                mp[v].push_back(Edge{u,w});
                if(judgeLoop(u,v)) { ok = true; }
            }
            if(ok)
            {
                printf("YES
    ");
                continue;
            }
            int ans = 0;
            for(int i=1; i<=n; i++)
            {
                if(fa[i]==i)//找到这个树的根节点(人为设置的)
                {
                    int root = BFS(i);
                    int temp = BFS(root);
                    ans = max(ans,d[temp]);
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    hadoop 配置
    spark 学习网站和资料
    spark-submit 提交任务及参数说明
    python 浮点运算
    nginx 和 php
    clojure 语法
    编程语言
    spark
    mvn 与 pom.xml
    偏导数与偏微分
  • 原文地址:https://www.cnblogs.com/sykline/p/10515583.html
Copyright © 2020-2023  润新知