湫湫系列故事——设计风景线
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。
现在已经勘探确定了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
接下去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
#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; }