[关闭]
@xiaoziyao 2020-10-30T13:57:54.000000Z 字数 1643 阅读 1003

CF835F Roads in the Kingdom解题报告

解题报告


题意

分析

首先,为了使图仍然联通,我们只能隔环上的边。

代码

  1. #include<stdio.h>
  2. #define inf 10000000000000000
  3. #define int long long
  4. const int maxn=200005,maxm=400005;
  5. int n,e,cnt,ans1,ans2,tot;
  6. int start[maxn],to[maxm],then[maxm],worth[maxm],vis[maxn],sum[maxn],c[maxn],w[maxn],f[maxn],pre1[maxn],pre2[maxn],pre3[maxn],suf1[maxn],suf2[maxn],suf3[maxn];
  7. inline int max(int a,int b){
  8. return a>b? a:b;
  9. }
  10. inline int min(int a,int b){
  11. return a<b? a:b;
  12. }
  13. inline void add(int x,int y,int z){
  14. then[++e]=start[x],start[x]=e,to[e]=y,worth[e]=z;
  15. }
  16. int find(int x,int last){
  17. if(vis[x])
  18. return x;
  19. vis[x]=-1;
  20. for(int i=start[x];i;i=then[i]){
  21. int y=to[i],tmp;
  22. if(y==last)
  23. continue;
  24. tmp=find(y,x);
  25. if(tmp){
  26. c[++cnt]=x,w[cnt]=worth[i],sum[cnt]=sum[cnt-1]+w[cnt],vis[x]=1;
  27. return x==tmp? 0:tmp;
  28. }
  29. }
  30. return 0;
  31. }
  32. void dfs(int x,int last){
  33. for(int i=start[x];i;i=then[i]){
  34. int y=to[i];
  35. if(vis[y]==1||y==last)
  36. continue;
  37. dfs(y,x);
  38. ans1=max(ans1,f[x]+f[y]+worth[i]);
  39. f[x]=max(f[x],f[y]+worth[i]);
  40. }
  41. }
  42. signed main(){
  43. scanf("%lld",&n);
  44. for(int i=1;i<=n;i++){
  45. int x,y,z;
  46. scanf("%lld%lld%lld",&x,&y,&z);
  47. add(x,y,z),add(y,x,z);
  48. }
  49. find(1,0);
  50. for(int i=1;i<=cnt;i++)
  51. dfs(c[i],0);
  52. tot=sum[cnt];
  53. pre1[0]=pre2[0]=pre3[0]=-inf;
  54. for(int i=1;i<=cnt;i++){
  55. pre1[i]=max(pre1[i-1],f[c[i]]+sum[i]);
  56. pre2[i]=max(pre2[i-1],f[c[i]]-sum[i]);
  57. pre3[i]=max(pre3[i-1],f[c[i]]+sum[i]+pre2[i-1]);
  58. }
  59. suf1[cnt+1]=suf2[cnt+1]=suf3[cnt+1]=-inf;
  60. for(int i=cnt;i>=1;i--){
  61. suf1[i]=max(suf1[i+1],f[c[i]]+sum[i]);
  62. suf2[i]=max(suf2[i+1],f[c[i]]-sum[i]);
  63. suf3[i]=max(suf3[i+1],f[c[i]]-sum[i]+suf1[i+1]);
  64. }
  65. ans2=inf;
  66. for(int i=1;i<=cnt;i++)
  67. ans2=min(ans2,max(max(pre3[i-1],suf3[i]),tot+pre1[i-1]+suf2[i]));
  68. printf("%lld\n",max(ans1,ans2));
  69. return 0;
  70. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注