BZOJ3573: [Hnoi2014]米特运输(树上乱搞)
2018-06-17 20:48:55来源:未知 阅读 ()
Submit: 1669 Solved: 1031
[Submit][Status][Discuss]
Description
Input
Output
输出文件仅包含一行,一个整数,表示最少的被重建(即修改储存器容量)的米特储存器的数目。
Sample Input
5
4
3
2
1
1 2
1 3
2 4
2 5
Sample Output
HINT
【样例解释】
一个最优解是将A[1]改成8,A[3]改成4,A[5]改成2。这样,2和3运给1的量相等,4和5运给2的量相等,且每天晚上六点的时候,1,2满,3,4,5空,满足所有限制条件。
Source
神题!!
此题有一个非常重要的性质:当一个点的权值确定之后,整棵树的权值就都确定了
盗用一下矩形方块大佬的图
那么我们可以固定一个数不变,观察此时根节点的值是多少
设$f[i]$表示当$i$号节点的权值不变时,根节点的值是多少
那么我们可以枚举每一个点,计算完成后对$f$数组排序,找出最长的权值相同的序列,然后再用总结点的数量减去它的长度,就是最终答案
但是根据数据范围不难看出,根节点的值会爆long long,
有两种解决方法:
1.考虑到所有的计算都是乘法,取log变为加法$log_x{ab}=log_x{a}+log_x{b}$
2.hash
速度差不多
反思:
刚开始的时候一直在考虑如何计算一个节点改变后整棵树的形态,但是这样的话问题就太复杂了,因此再遇到此类问题的时候一定要从宏观上去考虑,看看有没有更妙的方法
// luogu-judger-enable-o2 #include<cstdio> #include<vector> #include<cstring> #include<cmath> #include<algorithm> #define LL long long using namespace std; const int MAXN=1e6+10; #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<22,stdin),p1==p2)?EOF:*p1++) char buf[1<<22],*p1=buf,*p2=buf; inline int read() { char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } vector<int>v[MAXN]; int N; int val[MAXN],outder[MAXN]; double f[MAXN]; void dfs(int now, double times) { f[now] = times + log((double)val[now]); for(int i = 0;i < v[now].size();i++) dfs(v[now][i], times + log((double)outder[now])); } int main() { #ifdef WIN32 freopen("a.in","r",stdin); #endif N = read(); for(int i = 1;i <= N;i++) val[i] = read(); for(int i = 1;i <= N-1;i++) { int x = read(), y = read(); outder[x]++; v[x].push_back(y); } dfs(1,log((double)1)); sort(f+1,f+N+1); int now=0,ans=0; for(int i = 1;i <= N;i++) (f[i] - f[i-1] < 1e-8) ? ans = max(ans, ++now) : now = 1; printf("%d",N - ans); return 0; }
// luogu-judger-enable-o2 // luogu-judger-enable-o2 #include<cstdio> #include<vector> #include<cstring> #include<cmath> #include<algorithm> #define LL long long using namespace std; const int MAXN = 1e6+10, mod = 19260817; #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<22,stdin),p1==p2)?EOF:*p1++) char buf[1<<22],*p1=buf,*p2=buf; inline int read() { char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } vector<int>v[MAXN]; int N; int val[MAXN],outder[MAXN]; double f[MAXN]; void dfs(int now, double times) { f[now] = (LL)times * val[now] %mod ; for(int i = 0;i < v[now].size();i++) dfs(v[now][i], (LL)times * outder[now] % mod); } int main() { #ifdef WIN32 freopen("a.in","r",stdin); #endif N = read(); for(int i = 1;i <= N;i++) val[i] = read(); for(int i = 1;i <= N-1;i++) { int x = read(), y = read(); outder[x]++; v[x].push_back(y); } dfs(1,1); sort(f+1,f+N+1); int now=0,ans=0; for(int i = 1;i <= N;i++) (f[i] == f[i-1]) ? ans = max(ans, ++now) : now = 1; printf("%d",N - ans); return 0; }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 洛谷P3235 [HNOI2014]江南乐(Multi-SG) 2018-06-17
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash