zoukankan      html  css  js  c++  java
  • Solution -「洛谷 P6287」「COCI 2016-2017」Mag

    Description

    Link.

    定义一条链的价值为链上点权乘积除以节链上点数,求一条价值最小的链。

    Solution

    结论:答案链上最多包含一个 (2)(其余全为 (1)),并且不在链的两端点。

    证明:我们问题分成两个 ( exttt{pass})

    • ( exttt{pass 1})(forall u,s.t.x_{u}ge2)

    答案显然为 (min{x_{u}},uin V)

    • ( exttt{pass 2})(exists E'subset E,s.t.x_{u}=1,uin E'wedge x_{v}ge2,vin Esetminus E')

      • 我们设我们选出的链为大概这样的造型:

    [1 ightarrow1 ightarrowcdots ightarrow X ightarrow1 ightarrow1cdots ]

    即一堆 (1) 中夹了一个 (X)

    我们设 (X) 左边有 (l) 个节点,右边有 (r) 个节点。

    则价值为整条链 (frac{X}{l+r+1}),左边 (frac{1}{l}),右边 (frac{1}{r})

    为方便我们这里设 (l<r)

    那么左边的价值一定大于右边。

    这里假设 (frac{1}{r}>frac{X}{l+r+1}),则有 (X<frac{l+1}{r}+1),又 (rge l+1),所以 (frac{l+1}{r}le1)。(反之可以证伪,懒得写了 QwQ)

    所以有 (Xle2)

    (X eq1),所以 (X=2)

      • 我们设我们选出的链为大概这样的造型:

    [1 ightarrow1 ightarrowcdots ightarrow X ightarrow1 ightarrowcdots ightarrow1 ightarrow Y ightarrow1cdots ]

    即一堆 (1) 中夹了一个 (X) 一个 (Y)

    这里我们可以把 (Y) 以前当成 ( exttt{pass 2}) 的第一个类型,设其共有 (N) 个数。

    那么假设我们加入 (Y) 更优,即有 (frac{XY}{N+1}<frac{X}{N}),则有 (NY<N+1),由于 (Y eq1),所以加入 (Y) 是更劣的。

    后面的同理就可以推广了。

    于是得证 QwQ。

    然后我们就可以 DP 了。

    (f_{u,0/1}) 表示节点 (u) 权值为的情况下最优答案。

    转移就分类讨论一下:

    • (x_{u}=1)

    [egin{cases} f_{u,0}=max{f_{v,0}}+1 \ f_{u,1}=max{f_{v,1}}+1 end{cases} ]

    • (x_{u}=2)

    [f_{u,1}=max{f_{v,0}}+1 ]

    答案也需要分类讨论(这里设 (x,yin ext{son}(u))):

    • (x_{u}=1)

    答案为 (frac{1}{max{f_{x,0}+f_{y,0}+1}}),以及 (frac{2}{max{f_{x,0}+f_{y,1}}+1})

    • (x_{u}=2)

    答案为 (frac{2}{max{f_{x,0}+f_{y,0}+1}})

    用四个变量维护最大、次大的 (f_{0},f_{1}) 即可。

    #include <cstdio>
    
    const int MAXN = 1e6 + 5;
    
    int rint () {
    	int x = 0, f = 1; char c = getchar ();
    	for ( ; c < '0' || c > '9'; c = getchar () )	f = c == '-' ? -f : f;
    	for ( ; c >= '0' && c <= '9'; c = getchar () )	x = ( x << 3 ) + ( x << 1 ) + ( c & 15 );
    	return x * f;
    }
    
    template<typename _T>
    void wint ( _T x ) {
    	if ( x < 0 )	putchar ( '-' ), x = ~ x + 1;
    	if ( x > 9 )	wint ( x / 10 );
    	putchar ( x % 10 ^ '0' );
    }
    
    template<typename _T> _T MIN ( const _T x, const _T y ) { return x > y ? y : x; }
    
    struct starS {
    	int to, nx;
    	starS ( int T = 0, int N = 0 ) { to = T, nx = N; }
    } as[MAXN * 2];
    
    int n, cnt, Up = 1e9, Dn = 1, mnMg = 1e9, a[MAXN], f[MAXN][2], bgin[MAXN];
    
    void pushEdge ( const int u, const int v ) { as[++ cnt] = starS ( v, bgin[u] ); bgin[u] = cnt; }
    
    void checkUpt ( const int x, const int y ) { if ( Up * y > Dn * x )	Up = x, Dn = y; }
    
    void dfs ( const int u, const int lst ) {
    	int mx0 = 0, se0 = 0, mx1 = 0, se1 = 0;
    	for ( int i = bgin[u]; i; i = as[i].nx ) {
    		int v = as[i].to;
    		if ( v == lst )	continue;
    		dfs ( v, u );
    		if ( f[v][0] > f[mx0][0] )	se0 = mx0, mx0 = v;
    		else if ( f[v][0] > f[se0][0] )	se0 = v;
    		if ( f[v][1] > f[mx1][1] )	se1 = mx1, mx1 = v;
    		else if ( f[v][1] > f[se1][1] )	se1 = v;
    	}
    	if ( a[u] == 1 ) {
    		f[u][0] = f[mx0][0] + 1;
    		checkUpt ( 1, f[mx0][0] + f[se0][0] + 1 );
    		if ( ! mx1 )	return;
    		f[u][1] = f[mx1][1] + 1;
    		if ( mx0 != mx1 )	checkUpt ( 2, f[mx0][0] + f[mx1][1] + 1 );
    		else {
    			checkUpt ( 2, f[se0][0] + f[mx1][1] + 1 );
    			if ( se1 )	checkUpt ( 2, f[mx0][0] + f[se1][1] + 1 );
    		}
    	}
    	else if ( a[u] == 2 )	f[u][1] = f[mx0][0] + 1, checkUpt ( 2, f[mx0][0] + f[se0][0] + 1 );
    }
    
    int main () {
    	n = rint ();
    	for ( int i = 1, u, v; i < n; ++ i ) {
    		u = rint (), v = rint ();
    		pushEdge ( u, v ), pushEdge ( v, u );
    	}
    	for ( int i = 1; i <= n; ++ i )	a[i] = rint (), mnMg = MIN ( mnMg, a[i] );
    	if ( mnMg > 1 )	wint ( mnMg ), putchar ( '/' ), wint ( 1 ), putchar ( '
    ' );
    	else	dfs ( 1, 0 ), wint ( Up ), putchar ( '/' ), wint ( Dn ), putchar ( '
    ' );
    	return 0;
    }
    
  • 相关阅读:
    [Laravel] mac下通过 homestead 搭建环境 到运行项目
    Mac下Laravel的Homestead环境配置
    Window10 下安装 Laravel / Homestead 视频
    Windows 10下Laravel的开发环境安装及部署(Vagrant + Homestead)
    Apache 调用不同的 PHP 版本
    inux系统用户名和全名有什么区别
    oracle 学习day01
    rpm
    Linux下可以使用ps命令来查看Oracle相关的进程
    oracle 建用户
  • 原文地址:https://www.cnblogs.com/orchid-any/p/14035499.html
Copyright © 2011-2022 走看看