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

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

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
 
课程设计浪费了我一个星期,一个星期没打代码了。。
这个题的话无疑就是并查集判环+树的直径。
1.首先,利用并查集判环,如果没有环,那么肯定就是一棵树(森林)了。
2.树的直径的解法就是以任意一个点进行搜索,然后得到距离它最远的那个叶子结点,那么这个点必定是直径的"一端",证明过程的话我就不写了,然后以找到的这个点进行广搜,得到离这个叶子结点最远的那点肯定就是树的另一端。两点距离即为直径。
而这个题我先是以1点进行广搜,然后得到某个点之后再进行第二次搜索。结果太天真了,这个题的连通分量没有说只有一个啊!!所以我们应该对每个连通分量进行广搜。
给一组测试用例:
4 2
2 3 1
2 4 1
ans:2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N = ;
const int M = ;
int father[N];
struct Edge
{
int v,w,next;
} edge[M];
int head[N];
int n,m,tot;
void addEdge(int u,int v,int w,int &k)
{
edge[k].v = v,edge[k].w = w,edge[k].next = head[u],head[u] = k++;
}
int _find(int x)
{
if(x!=father[x]) father[x] = _find(father[x]);
return father[x];
}
void init()
{
tot = ;
for(int i=; i<=n; i++)
{
father[i] = i;
head[i] = -;
}
}
int dis[N];
bool vis[N];
bool used[N];
void bfs(int s)
{
memset(vis,false,sizeof(vis));
queue<int>q;
q.push(s);
vis[s] = true;
while(!q.empty())
{
int u = q.front();
q.pop();
for(int k = head[u]; k!=-; k=edge[k].next)
{
int w = edge[k].w,v = edge[k].v;
if(!vis[v])
{
used[v] = true;
vis[v] = true;
q.push(v);
dis[v] = max(dis[v],dis[u]+w);
}
}
} }
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==)
{
printf("0\n");
continue;
}
init();
bool flag = false;
for(int i=; i<=m; i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addEdge(u,v,w,tot);
addEdge(v,u,w,tot);
if(!flag)
{
int ru = _find(u);
int rv = _find(v);
if(ru==rv) flag = true;
else father[ru] = rv;
}
}
if(flag)
{
printf("YES\n");
continue;
}
memset(used,false,sizeof(used));
int res = ;
for(int i=; i<=n; i++)
{
if(used[i]) continue;
int s=i,t;
used[s] = true;
memset(dis,,sizeof(dis));
bfs(s);
int len = ;
for(int i=; i<=n; i++)
{
if(dis[i]>len)
{
len = dis[i];
t = i;
}
}
memset(dis,,sizeof(dis));
bfs(t);
int MAX = ;
for(int i=; i<=n; i++)
{
MAX = max(dis[i],MAX);
}
res = max(res,MAX); }
printf("%d\n",res);
}
return ;
}

hdu 4514(树的直径+并查集)的更多相关文章

  1. 【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT

    题目描述 给你 $n$ 个点,支持 $m$ 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. $n\le 3\times 10^5$ ,$ ...

  2. 【bzoj2870】最长道路tree 树的直径+并查集

    题目描述 给定一棵N个点的树,求树上一条链使得链的长度乘链上所有点中的最小权值所得的积最大. 其中链长度定义为链上点的个数. 输入 第一行N 第二行N个数分别表示1~N的点权v[i] 接下来N-1行每 ...

  3. 求树的直径+并查集(bfs,dfs都可以)hdu4514

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 这题主要是叫我们求出树的直径,在求树的直径之前要先判断一下有没有环 树的直径指的就是一棵树上面距 ...

  4. loj6038「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT

    题目传送门 https://loj.ac/problem/6038 题解 根据树的直径的两个性质: 距离树上一个点最远的点一定是任意一条直径的一个端点. 两个联通块的并的直径是各自的联通块的两条直径的 ...

  5. Codeforces 516D - Drazil and Morning Exercise(树的直径+并查集)

    Codeforces 题目传送门 & 洛谷题目传送门 这是一道 jxd 的作业题,感觉难度不是特别大(虽然我并没有自己独立 AC,不过也可能是省选结束了我的脑子也没了罢(((,就随便写写罢 u ...

  6. Codeforces 455C Civilization:树的直径 + 并查集【合并树后直径最小】

    题目链接:http://codeforces.com/problemset/problem/455/C 题意: 给你一个森林,n个点,m条边. 然后有t个操作.共有两种操作: (1)1 x: 输出节点 ...

  7. BZOJ 2870: 最长道路tree 树的直径+并查集

    挺好的一道题. 把所有点都离线下来,一个个往里加入就行了. #include <cstdio> #include <algorithm> #define N 100003 #d ...

  8. hdu 5458 Stability(树链剖分+并查集)

    Stability Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)Total ...

  9. [BZOJ3038]上帝造题的七分钟2 树状数组+并查集

    考试的时候用了两个树状数组去优化,暴力修改,树状数组维护修改后区间差值还有最终求和,最后骗了40分.. 这道题有好多种做法,求和好说,最主要的是开方.这道题过的关键就是掌握一点:在数据范围内,最多开方 ...

随机推荐

  1. 【模板】无旋Treap(FHQ)

    如题,这是一个模板... #include <algorithm> #include <iostream> #include <cstring> #include ...

  2. Windows7设置局域网文件共享

    首先要实现共享必须设置共享的机器与访问共享的机器在同一个工作组中. 右键桌面上的计算机图标=>属性 如果不一样的话,就需要点击[更改设置] 右键要共享的文件或者文件夹,点击[共享]打开共享标签: ...

  3. MySQL数据库的多种备份与多种还原

    一.备份 1.mysqldump 方法备份 mysqldump备份很简单,格式如下: mysqldump -u用户名 -p密码 数据库名> XX.sql 路径 例如: mysqldump -ur ...

  4. nrf开发笔记一开发软件

    nrf52810 的开发环境,比较主流的可以使用keil,iar亦可.sdk中,使用的是pca10040e,s112.虽然开发板共用一个型号(pca10040) keil5中,cmsis 需要4.5. ...

  5. 基于TCP协议的网络通讯流程

    不多说了,先上个图: 从上面的图中可以看出来,基于TCP协议进行通讯可以大致分成以下几个阶段: 1. 首先是在服务器端, TCP Sever调用socket(), bind(), listen()完成 ...

  6. [windows篇][关掉某些服务]

  7. [uiautomator篇] [4] 运行成功的日志打印---最后写一个脚本来实现

    Testing started at 18:23 ... 05/10 18:23:01: Launching ChangeTextBehaviorTestNo apk changes detected ...

  8. Thinkphp5 PDO操作mysql预处理中文字段出错问题

    Thinkphp5手册上建议不用中文表明和中文字段名 今天发现中文字出问题的地方了 $pdo = new PDO('mysql:host=localhost;dbname=xsfm_master', ...

  9. mq类----2

    手动应答方式 使用get my_consumer.php 消费者  生产者和上一篇 一样 <?php /** * Created by PhpStorm. * User: brady * Dat ...

  10. tomcat(不仅仅是tomcat)通过熵池解决在linux启动应用慢

    tomcat启动过程中报错 -Jul- ::] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web applica ...