CF572_Div2_D2
题意
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的更多相关文章
随机推荐
- Java并发机制的底层实现原理之volatile应用,初学者误看!
volatile的介绍: Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现 ...
- POJ 1166 The Clocks [BFS] [位运算]
1.题意:有一组3*3的只有时针的挂钟阵列,每个时钟只有0,3,6,9三种状态:对时针阵列有9种操作,每种操作只对特点的几个时钟拨一次针,即将时针顺时针波动90度,现在试求从初试状态到阵列全部指向0的 ...
- Redis的高并发、持久化、高可用架构设计
就是如果你用redis缓存技术的话,肯定要考虑如何用redis来加多台机器,保证redis是高并发的,还有就是如何让Redis保证自己不是挂掉以后就直接死掉了,redis高可用 我这里会选用我之前讲解 ...
- Java线程的生命周期与状态流转
上图是一个线程的生命周期状态流转图,很清楚的描绘了一个线程从创建到终止的过程. 这些状态的枚举值都定义在java.lang.Thread.State下 NEW:毫无疑问表示的是刚创建的线程,还没有开始 ...
- 20191017-4 alpha week 2/2 Scrum立会报告+燃尽图 03
此作业要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/9800 小组名称:“组长”组 组长:杨天宇 组员:魏新,罗杨美慧,王歆瑶,徐 ...
- Mysql 表与表之间的关系
一.前言 二.表与表之间的关系 (一) 一对多 (二) 一对一 (三) 多对多 一.前言 研究表与表之间的关系前,先要知道将所有数据存放在一张表中的弊端: 1.结构不清晰 ---> 不致命 2. ...
- cocos2dx Geometry Size和Rect
Size 代码都是基础代码不注释了,写一些特别的 1.赋值时可以接收Size和Vec2类型的值,保证的类型的兼容性 2.对运算符进行了重载,可以按照正常的数学逻辑运算 3..可以使用equals对比大 ...
- 关于非旋FHQ Treap的复杂度证明
非旋FHQ Treap复杂度证明(类比快排) a,b都是sort之后的排列(从小到大) 由一个排列a构造一颗BST,由于我们只确定了中序遍历=a,但这显然是不能确定一棵树的形态的. 由一个排列b构造一 ...
- 【一起学源码-微服务】Nexflix Eureka 源码五:EurekaClient启动要经历哪些艰难险阻?
前言 在源码分析三.四都有提及到EurekaClient启动的一些过程.因为EurekaServer在集群模式下 自己本身就是一个client,所以之前初始化eurekaServerContext就有 ...
- hadoop上下文信息获取方法
import java.io.IOException; import java.net.URI; import org.apache.hadoop.conf.Configuration; import ...