湫湫系列故事——设计风景线
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
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
2013腾讯编程马拉松初赛第二场(3月22日)
并查集判断是否为森林,求森林最长路。
const int Max_N = 100008 ;
const int Max_M = 1500008 ;
bool visited[Max_N] ;
bool used[Max_N] ;
int dist[Max_N] ;
int N , M ;
struct Edge{
int v ;
int w ;
int next ;
};
Edge edge[Max_M*2] ;
int List[Max_N] ;
int id ;
void add_edge(int u , int v , int w){
edge[id].v = v ;
edge[id].w = w ;
edge[id].next = List[u] ;
List[u] = id++ ;
}
int father[Max_N] ;
int find_father(int x){
if(x == father[x])
return x ;
else
return father[x] = find_father(father[x]) ;
}
void bfs(int s){
memset(dist , 0 , (N+1)*sizeof(int)) ;
memset(visited , 0 , (N+1)*sizeof(bool)) ;
visited[s] = 1 ;
queue<int> que ;
que.push(s) ;
int u , v , w ;
while(! que.empty()){
u = que.front() ;
used[u] = 1 ;
que.pop() ;
for(int e = List[u] ; e != -1 ; e = edge[e].next){
v = edge[e].v ;
w = edge[e].w ;
if(!visited[v]){
visited[v] = 1 ;
dist[v] = dist[u] + w ;
que.push(v) ;
}
}
}
}
void fun(int &ans , int u){
bfs(u) ;
int s = max_element(dist+1 , dist+1+N) - dist ;
bfs(s) ;
ans = max(ans , *max_element(dist+1 , dist+1+N)) ;
}
int main(){
int i , u , v , w , ok ;
while(scanf("%d%d" ,&N , &M) != EOF){
memset(List , -1 , (N+1)*sizeof(int)) ;
id = 0 ;
ok = 1 ;
for(i = 1 ; i <= N ; i++)
father[i] = i ;
for(i = 1 ; i <= M ; i++){
u = getint() ;
v = getint() ;
w = getint() ;
if(!ok)
continue ;
add_edge(u , v , w) ;
add_edge(v , u , w) ;
u = find_father(u) ;
v = find_father(v) ;
if(u == v){
ok = 0 ;
}
else{
father[u] = v ;
}
}
if(!ok){
puts("YES") ;
continue ;
}
int ans = 0 ;
memset(used , 0 , (1+N)*sizeof(bool)) ;
for(i = 1 ; i <= N ; i++){
if(!used[i])
fun(ans , i) ;
}
printf("%d\n" ,ans) ;
}
return 0 ;
}