小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;
}
全部评论

相关推荐

死在JAVA的王小美:哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈,我也是,让我免了一轮,但是硬气拒绝了
点赞 评论 收藏
分享
4 收藏 评论
分享
牛客网
牛客企业服务