Codeforces 1189D2. Add on a Tree: Revolution

Posted lltyyc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 1189D2. Add on a Tree: Revolution相关的知识,希望对你有一定的参考价值。

传送门

首先可以证明一颗树合法的充分必要条件是不存在某个节点的度数为 $2$

首先它是必要的,考虑任意一条边连接的两点如果存在某一点 $x$ 度数为 $2$ ,那么说明 $x$ 还有连一条边出去,那么连出去的那一条边和当前边的权值就永远一样

然后它是充分的,考虑进行如下操作:首先设当前边连接的两端分别为 $L,R$ ,如果 $L,R$ 只要存在某一个度数为 $1$ 显然合法

然后考虑 $L,R$ 度数不为 $1$ 的情况,那么 $L,R$ 一定分别存在两个儿子连向叶子,设为 $Lx,Ly,Rx,Ry$ 

设当前边的目标权值为 $x$ ,那么只要操作: $(Lx,Rx,x/2),(Ly,Ry,x/2),(Lx,Ly,-x),(Rx,Ry,-x)$ 即可,由于 $x$ 为偶数,所以 $x/2$ 一定为整数

因为这一题可以 $n^2$ ,所以直接按上面描述模拟即可

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<0||ch>9) { if(ch==-) f=-1; ch=getchar(); }
    while(ch>=0&&ch<=9) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const int N=1e5+7;
int n,a[N],b[N],c[N],du[N];
int fir[N],from[N<<1],to[N<<1],cntt;
inline void add(int a,int b) { from[++cntt]=fir[a]; fir[a]=cntt; to[cntt]=b; }
int find(int x,int fa)
{
    if(du[x]==1) return x;
    for(int i=fir[x];i;i=from[i])
        if(to[i]!=fa) return find(to[i],x);
}
struct dat {
    int x,y,z;
    dat (int _x=0,int _y=0,int _z=0) { x=_x,y=_y,z=_z; }
};
vector <dat> ans;
int main()
{
    n=read();
    for(int i=1;i<n;i++)
    {
        a[i]=read(),b[i]=read(); c[i]=read();
        add(a[i],b[i]); add(b[i],a[i]);
        du[a[i]]++,du[b[i]]++;
    }
    if(n==2) { printf("YES
1
1 2 %d
",c[1]); return 0; }
    for(int i=1;i<n;i++)
    {
        if(du[a[i]]==2||du[b[i]]==2) { printf("NO
"); return 0; }
        if(du[b[i]]==1) swap(a[i],b[i]);
        vector <int> L,R;
        for(int j=fir[a[i]];j;j=from[j])
            if(to[j]!=b[i]) L.push_back(find(to[j],a[i]));
        for(int j=fir[b[i]];j;j=from[j])
            if(to[j]!=a[i]) R.push_back(find(to[j],b[i]));
        if(L.size()==0)
            ans.push_back(dat(a[i],R[0],c[i]/2)),
            ans.push_back(dat(a[i],R[1],c[i]/2)),
            ans.push_back(dat(R[0],R[1],-c[i]/2));
        else
            ans.push_back(dat(L[0],R[0],c[i]/2)),
            ans.push_back(dat(L[1],R[1],c[i]/2)),
            ans.push_back(dat(L[0],L[1],-c[i]/2)),
            ans.push_back(dat(R[0],R[1],-c[i]/2));
    }
    printf("YES
%d
",int(ans.size()));
    for(auto A: ans) printf("%d %d %d
",A.x,A.y,A.z);
    return 0;
}

 

以上是关于Codeforces 1189D2. Add on a Tree: Revolution的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #572 (Div. 2)

Codeforces Round #740 (Div. 2, based on VK Cup 2021 - Final (Engine))ABCD1D2E题解

Codeforces Round #740 (Div. 2, based on VK Cup 2021 - Final (Engine))ABCD1D2E题解

CodeForces - 1189 E.Count Pairs (数学)

Codeforces 1189E. Count Pairs

Codeforces Round #740 (Div. 2, based on VK Cup 2021 - Final (Engine))