题目描述

Everyone knew it would only be a matter of time. So what? Faced for years on, a peril becomes the every-day reality. It loses its meaning...

Today the letter of the Bitotian char Bittard to the Byteotian king Byteasar was released to the public. Bitotia requested annexation of the whole Byteotia on pain of using the Bit Polarizing Magnet (BPM). If used, the BPM would make each and every road in Byteotia unidirectional. The enemy knows only too well that this could be a fatal blow to the minimalist Byteotian infrastructure - there is a unique way between each pair of towns.

How badly can the BPM damage the Byteotian infrastructure? Determine the minimum and the maximum number of such pairs of towns that it will still be possible to travel from one of them to the other while observing the new roads orientation.

给定一棵树,可以对每条边定向成一个有向图,这张有向图的可达点对数为树上有路径从u到达v的点对(u,v)个数。求最小可达点对数和最大可达点对数

输入

The first line of the standard input gives a single integer N (1<=N<=250000), the number of towns in Byteotia. The N-1 lines that follow describe these roads. Each such line holds two integers, U  and V (1<=U<=V<=N) , which indicate that there is a direct road (still bidirectional at the moment) linking the towns no.  and .

输出

Two integers should be printed to the first and only line of the standard output. The first number should be the minimum and the second - the maximum number of pairs of towns which could remain connected (though in one direction only) after the roads are polarized.

样例输入

4
1 2
1 3
1 4

样例输出

3 5
 
最少可到达点数很好求,就是n-1。因为每条边的贡献最少为1,将树黑白染色,奇数层染黑色,偶数层染白色,所有黑点指向白点,答案就是n-1。
最多的怎么求?显然是一些点指向一个点,那个点再指向剩下的点(证明最后再说)。
经过中间点的答案就是两边点数的乘积,那么中间点怎么选?显然要使两边点数尽可能相等,选重心就好了。
按01背包来选择一些子树,这样做时间复杂度显然是O(n^2),我们可以用bitset优化成O(n^2/32),但显然还是过不去。
考虑到子树大小大于√n的不超过√n个,所以可以将子树大小大于√n的暴力DP,剩下的将相同大小的合并后二进制拆分来DP。这样时间复杂度就变成了O(n√n/32)
最后证明一下为什么一定是找到一个中间点最优:
首先如果改变一棵树中所有边的指向,可到达点对数不变。
如果不是中间点最优,那么一定有一条路径x指向y,x至少有两条出边(假设第二条指向a),y至少有两条入边(假设第二条入边由b指过来),改变y,b之间的边及b子树中的边或改变x,a之间的边及a子树中的边,一定有一种情况能使答案更优,这样改变下去直到找到一个中间点。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<bitset>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int n;
int m;
int mn;
ll ans;
ll sum;
int x,y;
int tot;
int cnt;
int root;
int s[510];
int q[250010];
int d[250010];
int to[5000010];
int head[250010];
int next[500010];
int size[250010];
bitset<250010>f;
void add(int x,int y)
{
tot++;
next[tot]=head[x];
head[x]=tot;
to[tot]=y;
}
void dfs(int x)
{
sum+=d[x]-1;
size[x]=1;
int mx=0;
for(int i=head[x];i;i=next[i])
{
if(!d[to[i]])
{
d[to[i]]=d[x]+1;
dfs(to[i]);
size[x]+=size[to[i]];
mx=max(mx,size[to[i]]);
}
}
mx=max(mx,n-size[x]);
if(mx<mn)
{
mn=mx;
root=x;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
m=sqrt(n);
mn=n;
d[1]=1;
dfs(1);
memset(d,0,sizeof(d));
d[root]=1;
sum=0;
dfs(root);
for(int i=head[root];i;i=next[i])
{
q[++cnt]=size[to[i]];
}
f[0]=1;
for(int i=1;i<=cnt;i++)
{
if(q[i]<=m)
{
s[q[i]]++;
}
else
{
f=f|(f<<q[i]);
}
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=s[i];s[i]-=j,j<<=1)
{
f=f|(f<<(j*i));
}
if(s[i])
{
f=f|(f<<(s[i]*i));
}
}
for(int i=0;i<=n;i++)
{
if(f[i])
{
ans=max(ans,sum+(1ll*i*(n-i-1)));
}
}
printf("%d %lld",n-1,ans);
}

BZOJ3425[POI2013]Polarization——DP+bitset+分块的更多相关文章

  1. BZOJ3425 : Poi2013 Polarization

    最小值肯定是把树看作二分图,此时答案为$n-1$. 最大值一定是选取重心为根,任意一个子树要么全部指向根,要么全部背离根,这样可以制造最大的星型图. 统计出每个子树的大小后做01背包,如果小于$\sq ...

  2. BZOJ.3425.[POI2013]Polarization(DP 多重背包 二进制优化)

    BZOJ 洛谷 最小可到达点对数自然是把一条路径上的边不断反向,也就是黑白染色后都由黑点指向白点.这样答案就是\(n-1\). 最大可到达点对数,容易想到找一个点\(a\),然后将其子树分为两部分\( ...

  3. 【BZOJ3425】Poi2013 Polarization 猜结论+DP

    [BZOJ3425]Poi2013 Polarization Description 给定一棵树,可以对每条边定向成一个有向图,这张有向图的可达点对数为树上有路径从u到达v的点对(u,v)个数.求最小 ...

  4. HDU5716, HDU5745【dp+bitset】

    DP+bitset  HDU5716 dp[i][j] = dp[i-1][j-1] && (s[i] in set[j]); 第二维压bitset #include <bits ...

  5. hdu5745--La Vie en rose (DP+bitset)

    好题,学到新姿势! 题意:给两个字符串 a 和 b ,b可以进行变换,规则是可以任意交换相邻两个字符的位置,但是不可以有交叉(例如3和4交换,5和6交换 互不影响,但是2和3,3和4就不可以).求a中 ...

  6. hdu5745 La Vie en rose 巧妙地dp+bitset优化+滚动数组减少内存

    /** 题目:hdu5745 La Vie en rose 链接:http://acm.hdu.edu.cn/showproblem.php?pid=5745 题意:题目给出的变换规则其实就是交换相邻 ...

  7. 字符串匹配dp+bitset,滚动数组优化——hdu5745(经典)

    bitset的经典优化,即把可行性01数组的转移代价降低 bitset的适用情况,当内层状态只和外层状态的上一个状态相关,并且内层状态的相关距离是一个固定的数,可用bitset,换言之,能用滚动数组是 ...

  8. hdu 5745 La Vie en rose DP + bitset优化

    http://acm.hdu.edu.cn/showproblem.php?pid=5745 这题好劲爆啊.dp容易想,但是要bitset优化,就想不到了. 先放一个tle的dp.复杂度O(n * m ...

  9. HDU5745-La Vie en rose-字符串dp+bitset优化

    这题现场的数据出水了,暴力就能搞过. 标解是拿bitset做,转移的时候用bitset优化过的操作(与或非移位)来搞,复杂度O(N*M/w) w是字长 第一份标程的思路很清晰,然而后来会T. /*-- ...

随机推荐

  1. C语言中getch()、getche()和getchar()

    本文章为转载文章,文档贡献者wdzhangxiang 个人网址:www.baidu.com/p/wdzhangxiang 首先不要忘了,要用getch()必须引入头文件conio.h,以前学C语言的时 ...

  2. 源码篇:Python 实战案例----银行系统

    import time import random import pickle import os class Card(object): def __init__(self, cardId, car ...

  3. C#编程:从控制台读取数字的两种方式

    有时需要从控制台输入数字,就用到前面介绍的内容,数据转换,如:int num=int.Pares(Console.ReadLine()); int num=Convert.ToInt32(Consol ...

  4. flask_admin 笔记七 扩展功能

    高级功能 1,开启CSRF保护 要将CSRF保护添加到由ModelView实例生成的表单中,请通过指定form_base_class参数在ModelView子类中使用SecureForm类: from ...

  5. zookeeper Error contacting service 解决

    连接kafka集群,有一个kafka机器连接失败 到该kafka机器上查询kafka进程,发现没有, 再查看zookeeper状态,提示 Error contacting service. It is ...

  6. 对于ps基本操作的归纳

    1.开始新的制作 1)新建 快捷键:Ctrl+n      格式:宽高根据要求自选:颜色模式常用R(红)G(绿)B(蓝) 2)打开电脑上的图片 快捷键:Ctrl+o 2.选框工具 快捷键:M 作用:能 ...

  7. FreeCAD源码初步了解

    FreeCAD简介 FreeCAD是基于OpenCASCADE的开源CAD/CAE软件,完全开源(GPL的LGPL许可证),官方源码地址,详情可参考维基百科,百度百科等等. 如果要编译FreeCAD, ...

  8. B. Vasya and Isolated Vertices

    链接 [http://codeforces.com/contest/1065/problem/B] 题意 给你n个点,m条边,让你找最多孤立点和最少孤立点,不能有自环路 分析 对于最少max(0,n- ...

  9. linux及安全第四周总结

    学习内容:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用 一.用户态.内核态 权限分级——为了系统本身更稳定,使系统不宜崩溃.(并不是所有程序员缩写的代码都很健壮!!) x86 CP ...

  10. Linux内核设计与实现 第十七章

    1. 设备类型 linux中主要由3种类型的设备,分别是: 设备类型 代表设备 特点 访问方式 块设备 硬盘,光盘 随机访问设备中的内容 一般都是把设备挂载为文件系统后再访问 字符设备 键盘,打印机 ...