小A与欧拉路
小A与欧拉路
https://ac.nowcoder.com/acm/problem/22618
前置
首先我们需要知道什么是欧拉路和欧拉回路?
欧拉路:指从图中任意一个点开始到图中任意一个点结束的路径,并且图中每条边通过的且只通过一次
判定条件:图中只存在两个度数为奇数的点,其余全为偶数
欧拉回路:欧拉回路是指起点和终点相同的欧拉路
判定条件:图中所有的点度数为偶数
分析
有了前置芝士,这道题看起来就很可了
首先,我们需要选定起始点和终止点
然后我们发现
对于非这条直达路径上的边
他们都需要复制一边(因为进去之后还需要出来,一共经过两次)
所以我们设这条路径长度为s
那么答案为
所以我们需要s
尽可能得大
所以,我们需要求的就是直径了!
时间复杂度:
代码
//Nowcoder 22618 #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #define LL long long #define Cl(X,Y) memset((X),(Y),sizeof(X)) #define FOR(i,A,B) for(LL i=A;i<=B;i++) #define BOR(i,A,B) for(LL i=A;i>=B;i--) #define Debug(X) cerr<<#X<<" = "<<X<<" " #define Lowbit(X) (X & (-X)) #define Skip cout<<endl; #define INF 0x3f3f3f3f #define Mod 998244353 #define Rson (X<<1|1) #define Lson (X<<1) using namespace std; const LL MaxN=2e5+10; LL Up[MaxN],Down_one[MaxN],Down_two[MaxN],Max; LL Total,u,v,w,Opt,Sum; LL Next[MaxN<<1],Head[MaxN],End[MaxN<<1],Cur,Val[MaxN<<1]; LL Son[MaxN]; inline void File() { freopen(".in","r",stdin); freopen(".out","w",stdout); } inline void DFS_one(LL New,LL Pre) { for(LL i=Head[New];i;i=Next[i]) { if(End[i]==Pre) continue; DFS_one(End[i],New); if(Down_one[End[i]]+Val[i]>Down_one[New]) { Down_two[New]=Down_one[New]; Down_one[New]=Down_one[End[i]]+Val[i]; Son[New]=End[i]; } else if(Down_one[End[i]]+Val[i]>Down_two[New]) { Down_two[New]=Down_one[End[i]]+Val[i]; } } } inline void DFS_two(LL New,LL Pre,LL Temp) { if(Son[Pre]==New) { Up[New]=max(Up[Pre]+Temp,Down_two[Pre]+Temp); } else { Up[New]=max(Up[Pre]+Temp,Down_one[Pre]+Temp); } Max=max(Max,max(Down_one[New]+Down_two[New],Down_one[New]+Up[New])); for(LL i=Head[New];i;i=Next[i]) { if(End[i]==Pre) continue; DFS_two(End[i],New,Val[i]); } } inline void Add_Edge(LL From,LL To,LL Temp) { Next[++Cur]=Head[From]; Head[From]=Cur; End[Cur]=To; Val[Cur]=Temp; } signed main() { // File(); // ios::sync_with_stdio(false); scanf("%lld",&Total); FOR(i,2,Total) { scanf("%lld %lld %lld",&u,&v,&w); Add_Edge(u,v,w); Add_Edge(v,u,w); Sum+=w; } DFS_one(1,0); DFS_two(1,0,0); printf("%lld\n",2*Sum-Max); // fclose(stdin); // fclose(stdout); system("pause"); return 0; }