zoukankan      html  css  js  c++  java
  • wa2 图论

    【问题描述】
    山山最近开始玩一款叫做《白色相簿 2》的 Galgame。众所周知,Galgame 的剧情可以
    用一棵树来表示,其中非叶节点表示选项分支,叶子表示结局,树边表示支线剧情,剧情从
    树根开始向叶子方向进行。看完一段支线剧情所花的时间是一定的。
    《白色相簿 2》共有 n 个选项分支或结局,有 n - 1 段支线剧情,其中根节点被编号
    为 1 号。因为山山非常心急,于是他把自己的存档功能搞崩了。
    山山现在只能在固定的 k 个选项前存档,每次观看剧情需要从存档处开始。他想花最少
    的时间看一遍所有的剧情。 但是他现在有一个赛艇比赛要看,于是他希望你能帮他计算出
    这个最少时间。


    【输入格式】
    输入文件名为 wa2.in。
    第一行为两个正整数 n k。
    接下来一行 k 个正整数 s 1 s 2 s 3 ...s k ,表示 k 个存档点,保证 1 号节点是一个
    存档点。
    接下来 n - 1 行,每行三个整数 u v t,表示节点 u 和 v 之间的那段支线剧情需要花费 t
    的时间观看。
    (保证 u 是 v 的前置剧情或选项)


    【输出格式】
    输出文件名为 wa2.out。
    输出仅一行一个整数 ans 表示答案。


    【样例输入与输出】

    5 2

    1 2

    1 2 3

    2 3 2

    2 4 1

    1 5 6

    12


    其实这题没什么难度,就是需要注意几个方面:

    建双向边,dist值小心处理,叶节点的判断。

    我们看了题应该可以知道如果可以保存的话,那该点之上的剧情就不需要重新计算了,

    所以我们只要dfs一遍就可以得出答案。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    
    #define ll long long
    #define il inline
    #define db double
    
    using namespace std;
    
    il int gi()
    {
    	int x=0,y=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9')
    		{
    			if(ch=='-')
    				y=-1;
    			ch=getchar();
    		}
    	while(ch>='0'&&ch<='9')
    		{
    			x=x*10+ch-'0';
    			ch=getchar();
    		}
    	return x*y;
    }
    
    int head[100045],cnt;
    struct edge
    {
    	int next,to;
    	ll lon;
    }e[200045];
    
    il void add(int from,int to,ll lon)
    {
    	e[++cnt].next=head[from];
    	e[cnt].to=to;
    	e[cnt].lon=lon;
    	head[from]=cnt;
    }
    
    bool vis[100045];
    
    ll ans;
    
    bool p[100045];
    
    int du[100045];
    
    void dfs(int x,ll dist)
    {
    	if(vis[x])
    		ans+=dist,dist=0;
    	int r=head[x];
    	p[x]=1;
    	while(r!=-1)
    		{
    			int now=e[r].to;
    			if(!p[now])
    				dfs(now,dist+e[r].lon);
    			r=e[r].next;
    		}
    }
    
    int main()
    {
    	freopen("wa2.in","r",stdin);
    	freopen("wa2.out","w",stdout);
    	
    	memset(head,-1,sizeof(head));
    
    	int n=gi(),k=gi();
    	
    	for(int i=1;i<=k;i++)
    		vis[gi()]=1;
    
    	int x,y;
    	ll z;
    	for(int i=1;i<n;i++)
    		{
    			x=gi(),y=gi();
    			scanf("%lld",&z);
    			du[x]++;
    			du[y]++;
    			add(x,y,z);
    			add(y,x,z);
    		}
    
    	for(int i=1;i<=n;i++)
    		if(du[i]==1)
    			vis[i]=1;
    
    	dfs(1,0);
    
    	printf("%lld
    ",ans);
    
    	return 0;
    }
    
    PEACE
  • 相关阅读:
    toString() 与 JSON.stringify()
    ajax+node实现图片上传
    scrollHeight与offsetHeight
    【CSS】纯css实现立体摆放图片效果
    【逻辑】赛出25匹马的前3名
    【js】数组去重时间复杂度为n的方法
    【css】css2实现两列三列布局的方法
    初始原型链(三)
    初始原型链(二)
    织梦网站后台管理网站栏目管理项不显示问题解决办法
  • 原文地址:https://www.cnblogs.com/gshdyjz/p/7677386.html
Copyright © 2011-2022 走看看