F- Namori

http://agc004.contest.atcoder.jp/tasks/agc004_f


Time limit : 2sec / Memory limit : 256MB

Score : 2200 points

Problem Statement

You are given an undirected graph with N vertices and M edges. Here, N−1≤MN holds and the graph is connected. There are no self-loops or multiple edges in this graph.

The vertices are numbered 1 through N, and the edges are numbered 1 through M. Edge i connects vertices ai and bi.

The color of each vertex can be either white or black. Initially, all the vertices are white. Snuke is trying to turn all the vertices black by performing the following operation some number of times:

  • Select a pair of adjacent vertices with the same color, and invert the colors of those vertices. That is, if the vertices are both white, then turn them black, and vice versa.

Determine if it is possible to turn all the vertices black. If the answer is positive, find the minimum number of times the operation needs to be performed in order to achieve the objective.

Constraints

  • 2≤N≤105
  • N−1≤MN
  • 1≤ai,biN
  • There are no self-loops or multiple edges in the given graph.
  • The given graph is connected.

Partial Score

  • In the test set worth 1500 points, M=N−1.

Input

The input is given from Standard Input in the following format:

NMa1b1a2b2:aMbM

Output

If it is possible to turn all the vertices black, print the minimum number of times the operation needs to be performed in order to achieve the objective. Otherwise, print -1 instead.


Sample Input 1

Copy
6 5
1 2
1 3
1 4
2 5
2 6

Sample Output 1

Copy
5

For example, it is possible to perform the operations as shown in the following diagram:


Sample Input 2

Copy
3 2
1 2
2 3

Sample Output 2

Copy
-1

It is not possible to turn all the vertices black.


Sample Input 3

Copy
4 4
1 2
2 3
3 4
4 1

Sample Output 3

Copy
2

This case is not included in the test set for the partial score.


Sample Input 4

Copy
6 6
1 2
2 3
3 1
1 4
1 5
1 6

Sample Output 4

Copy
7

This case is not included in the test set for the partial score.

【分析】

  这题真神!!

  如果是一棵树的话。

  树是二分图,所以我们将他黑白染色,问题变成了,可以交换相邻的黑色和白色,使得最后图黑白倒置。

  把白色看成空格,黑色看成棋子,就是树上有x个棋子,你可以往空格里面移动,问你最少多少步到达目标状态。

  在树上,其实方案是唯一的,你求一下子树里面现在有多少个棋子,目标是多少个棋子,你就知道一定会从父亲那里运过来多少棋子(或者从这个运向父亲多少个棋子)

  这个是直接求就可以了的,就是$\sum ai-bi$

  黑点个数初末态不同则无解。

  当有环怎么办?

  我们分类讨论:

  1、构成奇环,多了的一条边连向的两点是同色的,就是说两个点那里可以同时加2个黑点或者同时减两个黑点,加/减多少个黑点你是知道的,(黑点奇偶初末态不同则无解),你就直接把那些黑点加上去,然后做法跟前面一样了。

  2、构成偶环,就是说多了的那条边也可以运棋子,假设这条边向上运了x个棋子,然后就也是树上的问题。你的ans最后会写成|Ai-x|或|Ai+x|或|Ai|的形式,这种形式的和很经典啦,就是数轴上的距离和,我们x取其中的中位数就能算出最优解。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Maxn 100010
#define LL long long
const int INF=; int mymin(int x,int y) {return x<y?x:y;} struct node
{
int x,y,next;
}t[Maxn*];
int len,first[Maxn]; void ins(int x,int y)
{
t[++len].x=x;t[len].y=y;
t[len].next=first[x];first[x]=len;
} int r1,r2,ad;
int sm[Maxn],ss[Maxn],ans,d[Maxn],h[Maxn];
int dfs(int x,int fa,int dep)
{
sm[x]=;ss[x]=dep;d[x]=dep;
if(x==r1||x==r2) sm[x]+=ad,ss[x]+=ad;
int tt=;
for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa)
{
int y=t[i].y;
tt+=dfs(y,x,-dep);
sm[x]+=sm[y];ss[x]+=ss[y];
}
if(x==r1) tt++;
if(x==r2) tt--;
if(tt==-) h[++h[]]=ss[x]-(sm[x]-ss[x]);
else if(tt==) h[++h[]]=(sm[x]-ss[x])-ss[x];
else ans+=abs(ss[x]-(sm[x]-ss[x]));
// ans+=abs(ss[x]-(sm[x]-ss[x]));
return tt;
} int ff[Maxn];
int ffa(int x)
{
if(ff[x]!=x) ff[x]=ffa(ff[x]);
return ff[x];
} int main()
{
// int T;
// scanf("%d",&T);
// while(T--)
{
int n,m;r1=r2=;
scanf("%d%d",&n,&m);
len=;
memset(first,,sizeof(first));
for(int i=;i<=n;i++) ff[i]=i;
for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
if(ffa(x)!=ffa(y))
{
ff[ffa(x)]=ffa(y);
ins(x,y);ins(y,x);
}
else r1=x,r2=y;
}
if(m==n-)
{
dfs(,,);
ans=;
for(int i=;i<=n;i++) ans+=abs(ss[i]-(sm[i]-ss[i]));
if(sm[]-ss[]!=ss[]) printf("-1\n");
else printf("%d\n",ans);
}
else
{
// printf("-2\n");
ad=;
dfs(,,);
if(d[r1]==d[r2])
{
ad=abs(ss[]-(sm[]-ss[]));
if(ad&) printf("-1\n");
else
{
ad/=;
if(ss[]>sm[]-ss[]) dfs(,,);
else dfs(,,);
ans=ad;
for(int i=;i<=n;i++) ans+=abs(ss[i]-(sm[i]-ss[i]));
printf("%d\n",ans);
}
}
else
{
h[]=;h[++h[]]=;
ans=;
dfs(,,);
if(sm[]-ss[]!=ss[]) printf("-1\n");
else
{
sort(h+,h++h[]);
int x=h[h[]/+];
for(int i=;i<=h[];i++) ans+=abs(h[i]-x);
printf("%d\n",ans);
}
}
}
}
return ;
}

【代码有点丑。。

2017-04-19 09:43:00

【atcoder F - Namori】**的更多相关文章

  1. 【Atcoder yahoo-procon2019-qual D】 Ears

    Atcoder yahoo-procon2019-qual D 题意:给你\(L\)个耳朵(???),以及一条范围从\(0\)到\(L\)的数轴,你可以选择一个出发点,从该点开始随意走动,如果经过了\ ...

  2. 【AtCoder】ARC067 F - Yakiniku Restaurants 单调栈+矩阵差分

    [题目]F - Yakiniku Restaurants [题意]给定n和m,有n个饭店和m张票,给出Ai表示从饭店i到i+1的距离,给出矩阵B(i,j)表示在第i家饭店使用票j的收益,求任选起点和终 ...

  3. 【AtCoder Regular Contest 082 F】Sandglass

    [链接]点击打开链接 [题意] 你有一个沙漏. 沙漏里面总共有X单位的沙子. 沙漏分A,B上下两个部分. 沙漏从上半部分漏沙子到下半部分. 每个时间单位漏1单位的沙子. 一开始A部分在上面.然后在r1 ...

  4. 【Wannafly挑战赛4】F 线路规划 倍增+Kruskal+归并

    [Wannafly挑战赛4]F 线路规划 题目描述 Q国的监察院是一个神秘的组织.这个组织掌握了整个帝国的地下力量,监察着Q国的每一个人.监察院一共有N个成员,每一个成员都有且仅有1个直接上司,而他只 ...

  5. 【AtCoder Regular Contest 082 A】Together

    [链接]点击打开链接 [题意] 给你n个数字,每个位置上的数字可以+1,不变,或-1,每个位置只能操作一次. 操作完之后,让你选一个数字x,然后统计a[i]==x的个数count. 问你count的最 ...

  6. 【AtCoder Regular Contest 082】Derangement

    [链接]点击打开链接 [题意] 在这里写题意 [题解] 贪心. 连续一块的p[i]==i的话,对答案的贡献就应该为(这个连续块的长度+1)/2; 长度为1的也正确. (也即两两相邻的互换位置.) [错 ...

  7. 【AtCoder Beginner Contest 074 D】Restoring Road Network

    [链接]h在这里写链接 [题意] 给你任意两点之间的最短路. 让你求出原图. 或者输出原图不存在. 输出原图的边长总和的最小值. [题解] floyd算法. 先在原有的矩阵上. 做一遍floyd. 如 ...

  8. 【AtCoder Beginner Contest 074 C】Sugar Water

    [链接]h在这里写链接 [题意] 让你在杯子里加糖或加水. (4种操作类型) 糖或水之间有一定关系. 糖和水的总量也有限制. 问你糖水浓度的最大时,糖和糖水的量. [题解] 写个dfs就好. 每次有4 ...

  9. 【AtCoder Beginner Contest 074 B】Collecting Balls (Easy Version)

    [链接]h在这里写链接 [题意] 看懂题目之后就会发现是道大水题. [题解] 在这里写题解 [错的次数] 0 [反思] 在这了写反思 [代码] #include <bits/stdc++.h&g ...

随机推荐

  1. 【leetcode 简单】第十一题 搜索插入位置

    给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置. 你可以假设数组中无重复元素. 示例 1: 输入: [1,3,5,6], 5 输 ...

  2. python初步学习-异常

    异常 异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行. 一般情况下,在python无法正常处理程序时就会发生一个异常. 异常是python对象,表示一个错误. 当python脚本 ...

  3. Web攻防系列教程之 Cookie注入攻防实战

    摘要:随着网络安全技术的发展,SQL注入作为一种很流行的攻击方式被越来越多的人所知晓.很多网站也都对SQL注入做了防护,许多网站管理员的做法就是添加一个防注入程序.这时我们用常规的手段去探测网站的SQ ...

  4. Warning: Permanently added the RSA host key for IP address '192.30.253.113' to the list of known hosts. Permission denied (publickey). fatal: Could not read from remote repository. Please make sure y

    这个应该是很多github新手经常出错的问题,这个就是没有在你github上添加一个公钥. 下面就直接说步骤: 1 可以用 ssh -T git@github.com去测试一下 图上可以明显看出缺少了 ...

  5. AES,SHA1,DES,RSA,MD5区别

    AES:更快,兼容设备,安全级别高: SHA1:公钥后处理回传 DES:本地数据,安全级别低 RSA:非对称加密,有公钥和私钥 MD5:防篡改 相关: 公开密钥加密(英语:public-key cry ...

  6. python基础之上下文管理器

    前言 关于计算器运行的上下文的概念,我的理解也不是很深:按我的理解就是程序在运行之前,其所需要的资源,运行环境等都会被序列化,然后加入到CPU的任务队列中,等待调度系统分配时间片执行.下面谈谈pyth ...

  7. gmail注册时“此电话号码无法用于进行验证”

    网上有几个方法,有说不要改默认地点,有说验证时直接写+86手机号,试了以后还是不行. 我的方法:换成IE浏览器,就可以验证了.

  8. ansible 下lineinfile详细使用 【转】

    转自 ansible 下lineinfile详细使用 - 散人 - 51CTO技术博客http://zouqingyun.blog.51cto.com/782246/1882367 一.简述 这几天在 ...

  9. C基础 如何让代码只执行一次

    1.0 最简单, 最高效的方式 C 代码运行起点 main 就是个大单例函数. 如果把函数注册在其里面, 那么一定很可以 :) // 某个库需要初始化的函数 void log_init(void) { ...

  10. C++——sort和stable_sort的若干区别

    版权声明:本文系作者原创,转载请注明出处. C++中sort和stable_sort的区别: sort是快速排序实现,因此是不稳定的:stable_sort是归并排序实现,因此是稳定的: 对于相等的元 ...