题目描述

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. Mybatis学习总结(四)——输入映射和输出映射

    在前面几篇文章的例子中也可以看到mybatis中输入映射和输出映射的身影,但是没有系统的总结一下,这篇博客主要对这两个东东做一个总结.我们知道mybatis中输入映射和输出映射可以是基本数据类型.ha ...

  2. 【小程序】当遇到bindTap绑定无法跳转到tabbar页面时

    如下图: 更换成navigator包裹跳转也不起作用. cart目录在app.json中定义在底部tabBar中 在小程序 导航 文档 最下方表示 所以,以上应改为

  3. odoo订餐系统之菜单设计

    1.model类的设计 class MyLunchProduction(osv.Model): _name = "mylunch.production" _description ...

  4. mui 下拉刷新和上拉加载

    <body> mui文档提供了两种不同模式的下拉刷新,具体情况看文档,链接:http://dev.dcloud.net.cn/mui/pulldown/ 单 webview 模式和 双 w ...

  5. POJ1850&&1019&&1942

    这三道题都水的难以想象,所以就放在一起写 1850 题目大意:有一种一种序列排列方式(如同题目中给出的例子),然后给你一个序列,问你这个序列的排名 首先我们先判断无解的情况,这个就很简单了. 由于题目 ...

  6. 数组排列组合问题——BACKTRACKING

    BACKTRACKING backtracking(回溯法)是一类递归算法,通常用于解决某类问题:要求找出答案空间中符合某种特定要求的答案,比如eight queens puzzle(将国际象棋的八个 ...

  7. Libp2p学习(一)

    Libp2p学习 参考资料:libp2p-specifications : https://github.com/libp2p/specs 持续更新ing 1. 介绍 Libp2p的实现目标是: 支持 ...

  8. GlusterFS分布式存储学习笔记

    分布式文件系统 分布式文件系统(Distributed File System)是指文件系统管理的物理存储资源并不直接与本地节点相连,而是分布于计算网络中的一个或者多个节点的计算机上.目前意义上的分布 ...

  9. centos7下安装php+memcached简单记录

    1)centos7下安装php 需要再添加一个yum源来安装php-fpm,可以使用webtatic(这个yum源对国内网络来说恐怕有些慢,当然你也可以选择其它的yum源) [root@nextclo ...

  10. A. A Prank

    题意 有数列从小到大排列,都是不同范围1~ 1000,问你最多去掉多少个数字还能复原 由于wrong很多发所以写一下 链接 [http://codeforces.com/contest/1062/pr ...