zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    赫尔维茨公式
    从解析几何的角度分析二次型
    Struts 1 Struts 2
    记一次服务器被入侵的调查取证
    契约式设计 契约式编程 Design by contract
    lsblk df
    Linux Find Out Last System Reboot Time and Date Command 登录安全 开关机 记录 帐号审计 历史记录命令条数
    Infrastructure for container projects.
    更新文档 版本控制 多版本并发控制
    Building Microservices: Using an API Gateway
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11728910.html
Copyright © 2011-2022 走看看