[AGC004F] Namori
Description
现在给你一张N个点M条边的连通图,我们保证N−1≤M≤N,且无重边和自环。
每一个点都有一种颜色,非黑即白。初始时,所有点都是白色的。
“全”想通过执行若干次某种操作的方式,来将所有的点变成黑色。操作方式如下:
选择一对颜色相同的相邻的节点(存在边直接连接彼此),将它们的颜色反转。即若原来都是白色,则都变成黑色,反之亦然。
现在“全”想知道,他能否通过执行这种操作以达到目的。如果可以,他还希望步数尽可能的少。
Input
第一行有两个正整数N和M(2≤N≤105,N−1≤M≤N)
接下来M行,每行2个正整数a和b(1≤a,b≤N),表示每条边连接的两个点。
Output
如果存在操作方案使得“全”能达到目的,请输出最少操作次数。
否则,请输出−1
题解:
分三类:树,奇环,偶环
1.树
我们可以吧两个相邻的两个颜色相同的点翻转转化为,我们把原树二分图染色,把两个相邻的两个不同颜色的点交换。那我们的目标就是把所有黑点变成白点,白点变为黑点
我们可以看做一个球入洞的问题,白点上都有一个球,黑点上都有一个洞。我们把每个球都放进一个洞里,问最小要移多少次才能使全部球都入洞。
那么方案可行的条件是球和洞的数量相等。
那么我们把白点权值设为1,黑点为-1,那么答案就为
\]
\(sum_i\) 为子树 \(i\) 的点权和(仔细想想能明白的)。
以上就是为树的解法。
2.奇环
奇环只不过是在树上加一条边罢了。
奇环多出来的那条边的两端肯定是同色的,所以对这条边操作一次可以使两个端点同时加上或是减少若干个球。
那我们如果图中球数和洞数不一样的话,我们可以通过操作这条边补成相等。
就像这样:
if(sum&1)return printf("-1"),0; //sum为球数和洞数的差
ans+=abs(sum>>1);
siz[S]-=sum>>1,siz[T]-=sum>>1;
奇环卒……
3.偶环:
偶环条的两个端点不是同一种颜色的,那我们可以从一个点运 \(x\) 个球到另一个点。
那我们其中一个点到 \(lca\) 的 \(sum\) 都要加 \(x\),另一边要减 \(x\)。
如图:
我们可以得到这些修改后的sum[i]。
我们换一下顺序全部写成 \(x-k[i]*sum[i]\) 的形式。
答案就为那些不受影响到点的sum和,加上 \(\sum_i |x-k[i]*sum[i]|\)
这不是初中的典型数学问题吗?找到一个x使得他到他到数轴上其他n个点的距离最小,
取中位数就行了。
AC……
COMPLETE CODE:
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
using namespace std;
long long ans=0;
int tot=0,h[100005];
int n,m,x,y,S,T,k[100005],siz[100005];
int s[100005],top;
bool odd;
struct Edge{
int x,next;
}e[200005];
inline void add_edge(int x,int y){
e[++tot].x=y;
e[tot].next=h[x],h[x]=tot;
}
void dfs1(int x,int fa){
for(int i=h[x];i;i=e[i].next){
if(e[i].x==fa)continue;
if(siz[e[i].x]){
if(siz[x]==siz[e[i].x])odd=true;
S=x,T=e[i].x;
}else{
siz[e[i].x]=-siz[x];
dfs1(e[i].x,x);
}
}
}
void dfs2(int x,int fa){
for(int i=h[x];i;i=e[i].next){
if(e[i].x==fa||(x==S&&e[i].x==T)||(x==T&&e[i].x==S))continue;
dfs2(e[i].x,x);
siz[x]+=siz[e[i].x];
k[x]+=k[e[i].x];
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&x,&y);
add_edge(x,y);
add_edge(y,x);
}
siz[1]=1,dfs1(1,0);
int sum=0;
for(int i=1;i<=n;i++)sum+=siz[i];
if(m==n-1){
if(sum)return printf("-1"),0;
}else{
if(odd){
if(sum&1)return printf("-1"),0;
ans+=abs(sum>>1);
siz[S]-=sum>>1,siz[T]-=sum>>1;
}else{
if(sum)return printf("-1"),0;
else k[S]=1,k[T]=-1;
}
}
dfs2(1,0);
for(int i=1;i<=n;i++){
if(k[i])s[++top]=k[i]*siz[i];
else ans+=abs(siz[i]);
}
s[++top]=0;
sort(s+1,s+top+1);
int mid=s[top+1>>1];
for(int i=1;i<=top;i++)ans+=abs(s[i]-mid);
printf("%lld",ans);
}
[AGC004F] Namori的更多相关文章
- 2017国家集训队作业[agc004f]Namori
2017国家集训队作业[agc004f]Namori 题意: 给你一颗树或环套树,树上有\(N\)个点,有\(M\)条边.一开始,树上的点都是白色,一次操作可以选择一条端点颜色相同的边,使它的端点颜色 ...
- AGC004F Namori 树形DP、解方程(?)
传送门 因为不会列方程然后只会树上的,被吊打了QAQ 不难想到从叶子节点往上计算答案.可以考虑到可能树上存在一个点,在它的儿子做完之后接着若干颜色为白色的儿子,而当前点为白色,只能帮助一个儿子变成黑色 ...
- Atcoder:AGC004F Namori
传送门 先考虑树,树是一个二分图. 看到是二分图并且每次是对两边的同色的点反色可以想到转化:让奇数层的点为黑,偶数为白,变成每次可以交换两个点的颜色. 把黑看成 \(-1\),白看成 \(1\),那么 ...
- [agc004f]Namori 贪心
Description 现在给你一张NN个点MM条边的连通图,我们保证N−1≤M≤NN−1≤M≤N,且无重边和自环. 每一个点都有一种颜色,非黑即白.初始时,所有点都是白色的. 想通过执行 ...
- AtCoder AGC004F Namori (图论)
题目链接 https://atcoder.jp/contests/agc004/tasks/agc004_f 题解 神仙题.. 首先考虑树的情况,树是二分图,因此假设我们对二分图进行黑白染色,那么操作 ...
- NOIp模拟赛二十九
又是受虐的一天呢~接下来四天都要打模拟赛QAQ 今日分数:0(100)+100+0=100 A题O(读入)结论题判断结果时没return 0被subtask卡成0分,喜提fstQAQ,B题DP,C题不 ...
- AtCoder刷题记录
构造题都是神仙题 /kk ARC066C Addition and Subtraction Hard 首先要发现两个性质: 加号右边不会有括号:显然,有括号也可以被删去,答案不变. \(op_i\)和 ...
- 贪心/构造/DP 杂题选做Ⅲ
颓!颓!颓!(bushi 前传: 贪心/构造/DP 杂题选做 贪心/构造/DP 杂题选做Ⅱ 51. CF758E Broken Tree 讲个笑话,这道题是 11.3 模拟赛的 T2,模拟赛里那道题的 ...
- 【agc004F】Namori
Portal -->agc004F Solution 好神仙的转化qwq 首先我们可以先考虑\(m=n-1\)的情况下,也就是树的情况下要怎么做 我们可以将这个问题转化一下:我们对这颗 ...
随机推荐
- 梁勇 java教材 编程练习题 第二章 2.6 键盘 读取一个在0 到 9999 之间的整数,并将该整数的各位数字相加。
import java.util.Scanner; /** * 需求:从键盘输入任意0~9999之间的整数,输出这个整数各位数字之和. * 思路:方法一,使用扫描器Scanner类,扫描控制台输入流 ...
- expect用法举例
1 expect -c 'spawn su - oracle -s check_tablespace.shexpect "Password:"send "oracle\n ...
- 非负随机变量X满足:(1-F(x)) 在 (0,+∞)积分为= E[X]
机器学习作业的第一题最后一问卡住了,要证明 非负随机变量X满足 1 - F(X) 在 (0,+∞)上的积分是E(X); 关键的地方是积分换序,看原来的答案真的很难理解,画个图一下就懂了,码个链接,便 ...
- centos7.4安装rabbitmq服务(3.7.10版本)
一.需要安装erlang版本依赖,可以使用二进制安装方式,也可以通过rpm安装,但是安装的时候会提示需要erlang版本>=19.3,而且直接默认yum仓库中的版本较低.,为了节省时间,文章中直 ...
- 最新Python3.6从入门到高级进阶实战视频教程
点击了解更多Python课程>>> 最新Python3.6从入门到高级进阶实战视频教程 第1篇 Python入门导学 第2篇 Python环境装置 第3篇 了解什么是写代码与Pyth ...
- 【Ecshop】将内置的 FCkeditor 更换为 UEditor
1.下载UE,解压到includes/,更名目录名为ueditor 注意更改配置后端文件上传路径,参考文档 2.修改admin/includes/lib_main.php,添加 /** * 生成编辑器 ...
- PHP之基本目录操作
一.创建目录 mkdir ($pathname, $mode = 0777, $recursive = false, $context = null) $pathname: 目录路径 $mode : ...
- A * B Problem Plus HDU - 1402 (FFT)
A * B Problem Plus HDU - 1402 (FFT) Calculate A * B. InputEach line will contain two integers A and ...
- Codeforces Round #464 (Div. 2) C. Convenient For Everybody
C. Convenient For Everybody time limit per test2 seconds memory limit per test256 megabytes Problem ...
- HDU 6228 tree 简单思维树dp
一.前言 前两天沈阳重现,经过队友提点,得到3题的成绩,但是看到这题下意识觉得题目错了,最后发现实际上是题目读错了....GG 感觉自己前所未有的愚蠢了....不过题目读对了也是一道思维题,但是很好理 ...