题意

http://codeforces.com/contest/1189/problem/D2


思考

显然地,如果出现度数为2且两条出边边权不相同的情况,是无法构造合法方案的。

下面考虑缩边后的树,此时每个非叶子节点的度数一定大于等于3。

枚举每个非叶子节点,将其重新作为树的根,并尝试将它所有的出边都达到要求。我们先找到它代表的所有叶子,分两种情况考虑:

1.一条边以下只有一个叶子。如下图所示,红色的路径代表+w/2,w为该边的边权,蓝色路径代表-w/2,能达到平衡。

2.一条边以下不止一个叶子。如下图所示,我们要求选定边的子树中挑出的两个叶子的lca的深度必须最大,否则无法消除影响。此处可以挑选dfn最大和最小的那两个。

总复杂度O(n^2)。注意特判一条链的情况。


代码

 #include<bits/stdc++.h>
using namespace std;
const int maxn=2E3+;
int n;
int deg[maxn*],hh[maxn];
int tot,haha;
bool dot[maxn];
vector<int>what[maxn];
vector<int>wait;
double w[maxn];
map<pair<int,int>,bool>vis;
inline pair<int,int>M(int x,int y)
{
if(x>y)
swap(x,y);
return make_pair(x,y);
}
struct edge
{
int to,next;
double w;
};
struct note
{
int x,y;
double d;
note(int a=,int b=,double c=)
{
x=a,y=b,d=c;
}
};
vector<note>ans;
struct graph
{
int head[maxn*],size;
edge E[maxn*];
inline void add(int u,int v,double w)
{
E[++size].to=v;
E[size].next=head[u];
E[size].w=w;
head[u]=size;
}
void get(int u,int F,int num)
{
for(int i=head[u];i;i=E[i].next)
{
int v=E[i].to;
if(v==F)
continue;
if(u==F)
{
w[++num]=E[i].w;
hh[num]=v;
get(v,u,num);
}
else
get(v,u,num);
}
if(deg[u]==)
what[num].push_back(u);
if(u==F)
for(int i=;i<=num;++i)
{
if(vis[M(u,hh[i])])
continue;
if(what[i].size()==)
{
int u1=what[i][];
int x=what[i+<=num?i+:i+-num][];
int y=what[i+<=num?i+:i+-num][];
double d=w[i]/;
ans.push_back(note(u1,x,d));
ans.push_back(note(u1,y,d));
ans.push_back(note(x,y,-d));
vis[M(u,hh[i])]=;
}
else
{
int u1=what[i][],u2=what[i][what[i].size()-];
int x=what[i+<=num?i+:i+-num][];
int y=what[i+<=num?i+:i+-num][];
double d=w[i]/;
ans.push_back(note(u1,x,d));
ans.push_back(note(u2,y,d));
ans.push_back(note(u1,u2,-d));
ans.push_back(note(x,y,-d));
vis[M(u,hh[i])]=;
}
}
}
void find(int u,int F,int last)
{
dot[u]=;
if(deg[u]!=)
{
haha=last;
wait.push_back(u);
return;
}
for(int i=head[u];i;i=E[i].next)
{
int v=E[i].to;
if(v==F)
continue;
if(last==)
{
find(v,u,E[i].w);
last=E[i].w;
}
else if(last==E[i].w)
find(v,u,E[i].w);
else
{
cout<<"NO"<<endl;
exit();
}
}
}
int sum;
void getsize(int u,int F)
{
++sum;
for(int i=head[u];i;i=E[i].next)
{
int v=E[i].to;
if(v==F)
continue;
getsize(v,u);
}
}
}source,G;
int main()
{
ios::sync_with_stdio(false);
cin>>n;
for(int i=;i<=n;++i)
{
int x,y;
double z;
cin>>x>>y>>z;
source.add(x,y,z);
source.add(y,x,z);
++deg[x],++deg[y];
}
int P1=,P2=;
for(int u=;u<=n;++u)
{
if(deg[u]==)
{
if(!dot[u])
{
source.find(u,u,);
wait.clear();
G.add(wait[],wait[],haha);
G.add(wait[],wait[],haha);
P1=wait[],P2=wait[];
}
continue;
}
for(int i=source.head[u];i;i=source.E[i].next)
{
int v=source.E[i].to;
haha=source.E[i].w;
if(deg[v]!=)
G.add(u,v,source.E[i].w);
}
}
cout<<"YES"<<endl;
G.getsize(P1,P1);
if(G.sum==)
{
cout<<<<endl;
cout<<P1<<" "<<P2<<" "<<haha<<endl;
return ;
}
for(int u=;u<=n;++u)
{
if(deg[u]==)
continue;
for(int i=;i<=n;++i)
what[i].clear();
G.get(u,u,);
}
int del=;
for(int i=;i<ans.size();++i)
if(abs(ans[i].d-)<=0.01)
++del;
cout<<ans.size()-del<<endl;
for(int i=;i<ans.size();++i)
if(abs(ans[i].d-)>0.01)
cout<<ans[i].x<<" "<<ans[i].y<<" "<<ans[i].d<<endl;
return ;
}

CF572_Div2_D2的更多相关文章

随机推荐

  1. 【Kubernetes】架构全图

    K8s是什么 Kubernetes是Google开源的容器集群管理系统.它构建在Docker技术之上,为容器化的应用提供资源调度.部署运行.服务发现.扩容缩容等一整套功能. K8s能做什么 ①容器的自 ...

  2. c++修改系统环境变量 (修改注册表以后,立刻使用SendMessageTimeout(HWND_BROADCAST进行广播)

    #include "stdafx.h" #include "addPath.h" #define _AFXDLL #include <afxwin.h&g ...

  3. 大数据基石——Hadoop与MapReduce

    本文始发于个人公众号:TechFlow 近两年AI成了最火热领域的代名词,各大高校纷纷推出了人工智能专业.但其实,人工智能也好,还是前两年的深度学习或者是机器学习也罢,都离不开底层的数据支持.对于动辄 ...

  4. [梁山好汉说IT] 熵的概念 & 决策树ID3如何选择子树

    [梁山好汉说IT] 熵的概念 & 决策树ID3如何选择子树 0x00 摘要 记录对概念的理解,用梁山好汉做例子来检验是否理解正确. 0x01 IT概念 1. 事物的信息和信息熵 1.1 事物的 ...

  5. c# T4模板生成实体类(sqlserver)

    1.用vs新建tt文件. 2.tt文件保存就自动运行 3.tt文件代码如下,设置生成cs文件的命名空间和生成地址 <#@ template language="C#" hos ...

  6. 洛谷p-1522又是Floyd

    挺简单一个题,可惜当时没想到,有点巧妙丫! #include<cstdio> #include<iostream> #include<cstring> #inclu ...

  7. 【题解】有标号的DAG计数3

    [HZOI 2015] 有标号的DAG计数 III 我们已经知道了\(f_i\)表示不一定需要联通的\(i\)节点的dag方案,考虑合并 参考[题解]P4841 城市规划(指数型母函数+多项式Ln), ...

  8. 洛谷$P$2468 粟粟的书架 $[SDOI2010]$ 主席树

    正解:主席树 解题报告: 传送门! 题目大意是说,给定一个矩形,然后每次会给一个,这个大矩形中的一个小矩形,询问从小矩形中最少选多少个数字能满足它们之和大于等于给定数字$x$ 看起来很神的样子,完全不 ...

  9. js获取当前农历时间

    <template> <div class="gaia-header"> <img alt="gaia_logo" src=&qu ...

  10. iscsi,nfs

    存储概述 存储的目标 存储是根据不同的应用环境通过采取合理.安全.有效的方式将数据保存到某些介质上并能保证有效的访问. 一方面它是数据临时或长期驻留的物理媒介. 另一方面,它是保证数据完整安全存放的方 ...