樹的直徑和並查集判環
阿新 • • 發佈:2019-02-10
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<queue> #define maxn 2000001 #define maxe 100001 using namespace std; int n,m; int first[maxe],nxt[maxn],to[maxn],e,cost[maxn]; int fa[maxe]; void add(int u,int v,int c){ to[e]=v;cost[e]=c;nxt[e]=first[u];first[u]=e++; } int finds(int x){ if(fa[x]==x)return fa[x]; else return fa[x]=finds(fa[x]); } void unit(int a,int b){ int x=finds(a); int y=finds(b); if(x==y)return ; else fa[x]=y; return ; } int d[maxe]; int bfs(int s){ memset(d,-1,sizeof d); queue<int>q; q.push(s); d[s]=0; while(!q.empty()){ int u=q.front(); q.pop(); for(int i=first[u];~i;i=nxt[i]){ int v=to[i]; if(d[v]==-1){ d[v]=d[u]+cost[i]; q.push(v); } } } int id=-1; for(int i=1;i<=n;i++){ if(id==-1||d[i]>d[id])id=i; } return id; } int maxlen(int s){ int a=bfs(s); int b=bfs(a); return d[b]; } int main() { int u,v,c; freopen("in.txt","r",stdin); while(scanf("%d%d",&n,&m)!=EOF){ bool flag=false; e=0; memset(first,-1,sizeof first); for(int i=1;i<=n;i++) fa[i]=i; for(int i=0;i<m;i++){ scanf("%d%d%d",&u,&v,&c); add(u,v,c); add(v,u,c); if(finds(u)==finds(v))flag=true; unit(u,v); } if(flag)puts("YES"); else{ printf("%d\n",maxlen(1)); } } }
湫湫系列故事——設計風景線
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 3218 Accepted Submission(s): 578
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