题目描述

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. JAVA中map的分类和各自的特性

    java为数据结构中的映射定义了一个接口java.util.Map,他实现了四个类,分别是:HashMap,HashTable,LinkedHashMapTreeMap Map不允许键重复,但允许值重 ...

  2. oracle pls-00382:表达式类型错误

    转载至:pls-00382:表达式类型错误 错误:pls-00382:表达式类型错误 如何产生: 我是在将一个动态sql付给一个nvarchar2变量是出现这个错误的,示例代码如下: declare ...

  3. TCP/IP与OSI模型

  4. Multiple “order by” in LINQ(转载)

    问: I have two tables, movies and categories, and I get an ordered list by categoryID first and then ...

  5. Luogu4630 APIO2018 Duathlon 圆方树、树形DP

    传送门 要求的是一条按顺序经过\(s,t,c\)三个点的简单路径.简单路径的计数问题不难想到点双联通分量,进而使用圆方树进行求解. 首先将原图缩点,对于一个大小为\(size\)的点双联通分量内,在这 ...

  6. Linux下安装jdk+maven +git

            Linux系统下的操作,一直不是很熟悉.作为一名java开发工程师,感到很惭愧.因此把自己的阿里云服务器安装环境相关的东西给记录下来,方便后续查阅.         本文所采用的Lin ...

  7. HNOI2018简要题解

    HNOI2018简要题解 D1T1 寻宝游戏 题意 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为 ...

  8. SQL行转列汇总 (转)

    PIVOT 用于将列值旋转为列名(即行转列),在 SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT 的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )A ...

  9. Authorize的Forms认证

    页面请求步骤: 1.登录地址: http://localhost:4441/SysLogin/AdminLogin 2.登陆成功地址:http://localhost:4441/Frame/MainF ...

  10. 针对Nginx日志的相关运维操作记录

    在分析服务器运行情况和业务数据时,nginx日志是非常可靠的数据来源,而掌握常用的nginx日志分析命令的应用技巧则有着事半功倍的作用,可以快速进行定位和统计. 1)Nginx日志的标准格式(可参考: ...