一、题目描述:
给你一棵
求任意去掉一条边之后,在保持所有点依然都连通的情况下,直径的最小值。
数据范围:
二、解题思路:
首先我们找出环,我用的是拓扑排序,便于找出环上的点。
考虑把这个图看成几棵分开的树,他们的根都在同一个环上,然后分类讨论:
至此,这个题终于分析完了。时间复杂度
三、完整代码:
1 #include<iostream> 2 #define N 200010 3 #define ll long long 4 using namespace std; 5 ll n,U,V,W,cc,ans1,ans2; 6 ll du[N],p1[N],p2[N],v1[N],v2[N]; 7 ll c[N],f[N],q[N],a1[N],a2[N],val[N]; 8 ll l1[N],l2[N],fl[N],r1[N],r2[N],fr[N]; 9 struct EDGE{ 10 ll v,w,nxt; 11 }edge[N*2]; 12 ll head[N],cnt; 13 void add(ll u,ll v,ll w) 14 { 15 edge[++cnt].v=v;edge[cnt].w=w; 16 edge[cnt].nxt=head[u];head[u]=cnt; 17 } 18 void top_sort() 19 { 20 ll l=1,r=0; 21 for(ll i=1;i<=n;i++) 22 if(du[i]==1) 23 q[++r]=i,v1[i]=1; 24 while(l<=r) 25 { 26 ll u=q[l];l++; 27 for(ll i=head[u];i!=-1;i=edge[i].nxt) 28 { 29 ll to=edge[i].v;du[to]--; 30 if(du[to]==1&&!v1[to]) 31 v1[to]=1,q[++r]=to; 32 } 33 } 34 } 35 void dfs1(ll u,ll ff) 36 { 37 for(ll i=head[u];i!=-1;i=edge[i].nxt) 38 if(edge[i].v!=ff&&!v1[edge[i].v]) 39 { 40 v1[edge[i].v]=v2[edge[i].v]=1; 41 c[++cc]=edge[i].v,val[cc]=edge[i].w; 42 dfs1(edge[i].v,u);break; 43 } 44 } 45 void dfs2(ll s,ll u,ll ff) 46 { 47 for(ll i=head[u];i!=-1;i=edge[i].nxt) 48 { 49 ll to=edge[i].v; 50 if(v2[to])continue; 51 v2[to]=1;dfs2(s,to,u); 52 ll t=a1[to]+edge[i].w; 53 if(t>a1[u]) a2[u]=a1[u],a1[u]=t; 54 else if(t>a2[u]) a2[u]=t; 55 } 56 f[s]=a1[u],ans1=max(ans1,a1[u]+a2[u]); 57 } 58 int main() 59 { 60 ios::sync_with_stdio(false); 61 cin.tie(0);cout.tie(0); 62 cin>>n; 63 for(ll i=1;i<=n;i++) 64 head[i]=-1; 65 for(ll i=1;i<=n;i++) 66 { 67 cin>>U>>V>>W; 68 add(U,V,W),du[U]++; 69 add(V,U,W),du[V]++; 70 } 71 top_sort(); 72 for(ll i=1;i<=n;i++) 73 if(!v1[i]) 74 { 75 dfs1(i,0); 76 break; 77 } 78 for(ll i=1;i<=cc;i++) 79 dfs2(i,c[i],0); 80 for(ll i=1;i<=cc;i++) 81 p1[i]=p1[i-1]+val[i]; 82 for(ll i=cc;i>=1;i--) 83 p2[i-1]=p2[i]+val[i]; 84 l1[0]=r1[cc+1]=-1e18,ans2=1e18; 85 for(ll i=1;i<=cc;i++) 86 { 87 l1[i]=max(l1[i-1],f[i]-p1[i]); 88 l2[i]=max(l2[i-1],f[i]+p1[i]); 89 fl[i]=max(fl[i-1],f[i]+p1[i]+l1[i-1]); 90 } 91 for(ll i=cc;i>=1;i--) 92 { 93 r1[i]=max(r1[i+1],f[i]-p2[i]); 94 r2[i]=max(r2[i+1],f[i]+p2[i]); 95 fr[i]=max(fr[i+1],f[i]+p2[i]+r1[i+1]); 96 } 97 for(ll i=1;i<=cc;i++) 98 { 99 ll t1=l2[i-1]+r2[i]; 100 ll t2=fl[i-1],t3=fr[i]; 101 ans2=min(ans2,max(t1,max(t2,t3))); 102 } 103 cout<<max(ans1,ans2)<<'\n'; 104 return 0; 105 }
四、写题心得:
这个题想了一整天,不过确实是一道好题。加油!拜拜!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】