湫湫系列故事——设计风景线
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\n");
else {
for (int i = 1; i <= n; i++) {
//如果节点所在的树没被访问过
if (!used[i]&& par[i] == i) {
bfs(i), bfs(s);
maxx = max(maxx, ans);
}
}
printf("%d\n", maxx);
}
}
return 0;
}