• 3210. 【JSOI2013】旅行时的困惑


    Description&Data Constraint

    喜爱旅游的Will最近在热带岛国Waldives度假。Waldives是由很多岛屿组成的。当地政府希望建立一些新的公交线路(交通工具当然是快艇了),但是却遇到了麻烦。作为计算机科学家的Will自然愿意挺身而出了。

    Waldives有 (N) 个小岛。目前的交通系统中包含 (N-1) 条快艇专线,每条快艇专线连接两个岛。这 (N-1) 条快艇专线恰好形成了一棵树。

    由于特殊的原因,所有 (N-1) 条快艇专线都是单向的。这导致了很多岛屿之间不能相互到达。因此,Waldives政府希望新建一些公交线路,使得建设完毕后,任意两个小岛都可以互相到达。为了节约开支,政府希望建设最少的公交线路。

    同时,出于规划考虑,每一条公交线路都有如下的要求:

    1. 每一条交通线路包含若干条连续的快艇专线,你可以认为一条公交线路对应树上的一条路径,而其所包含的若干快艇专线则对应树上被这条路径所覆盖的树边(也就是之前已经存在的某个快艇专线);

    2. 显然一条交通线路只能覆盖树上任意一条边至多一次;

    3. 公交线路中所包含的每一个快艇专线都是有方向的,并且与其所覆盖的树边的方向相反;

    4. 不同的公交线路可以覆盖树上相同的点或者相同的边。

    Waldives的 (N) 个岛屿分别从 0 到 (N-1) 编号。现在给出Waldives已有的快艇专线信息,请计算最少所需要新建的交通线路的数量。

    对于 (100\%) 的数据满足 (Nle10^5)

    Solution

    可以证明,如果一条公交线路可以在子树内建成,就不会在往子树外走。

    简单的证明:如果当前子树内有可以连的线路,如果往外走,要么与当前连边数一致,要么多连,答案不会更优。

    因此考虑贪心。设 (a_i)(b_i) 表示父亲要走过来多少和要往父亲走多少。

    对于当前节点 (x),它的子节点 (son) 只有 (a_i)(b_i) 中的一个可以传递到 (x),那么另一个就可以记录答案。

    另外,对于节点 (x),优先让其在内部建线路,剩余的再传递上去。

    Code

    #include<cstdio>
    #include<algorithm>
    #define N 100005
    using namespace std;
    struct ndoe
    {
    	int to,next,head,fx;
    }tree[N<<1];
    int n,x,y,ans,tot,a[N],b[N];
    void add(int x,int y,int opt)
    {
    	tree[++tot].to=y;
    	tree[tot].fx=opt;
    	tree[tot].next=tree[x].head;
    	tree[x].head=tot;
    }
    void dfs(int x,int fa)
    {
    	for (int i=tree[x].head;i;i=tree[i].next)
    	{
    		int v=tree[i].to;
    		if (v==fa) continue;
    		dfs(v,x);
    		if (tree[i].fx)//看能传递哪一部分,另外一部分计入答案
    		{
    			ans+=a[v];
    			b[x]+=max(b[v],1);
    		}
    		else
    		{
    			ans+=b[v];
    			a[x]+=max(a[v],1);
    		}
    	}
    	int t=min(a[x],b[x]);
    	a[x]-=t;b[x]-=t;ans+=t;//优先在内部连边
    }
    int main()
    {
    	scanf("%d",&n);
    	for (int i=1;i<n;++i)
    	{
    		scanf("%d%d",&x,&y);
    		add(x+1,y+1,1);add(y+1,x+1,0);
    	}
    	dfs(1,0);
    	printf("%d
    ",ans+max(a[1],b[1]));
    	return 0;
    }
    
  • 相关阅读:
    采用NAND Flash启动时出现Kernel panic not syncing: No init found错误
    ubuntu 11.10 安装小企鹅fcitx输入法
    UBoot中设定的bootdelay参数不起作用
    python 数据类型
    python运算符
    python符号//、%和/运算
    pytho 基本数据类型
    Python 开篇
    mmsplayer v2 java 之(mmsPlayer 播放类)
    mmsplayer v2 java 之(mmsTrack 音频类)
  • 原文地址:https://www.cnblogs.com/Livingston/p/15368258.html
Copyright © 2020-2023  润新知