zoukankan      html  css  js  c++  java
  • P3931 SAC E#1

    P3931 SAC E#1 - 一道难题 Tree

    2017-10-07


    题目背景

    冴月麟和魏潇承是好朋友。


    题目描述

    冴月麟为了守护幻想乡,而制造了幻想乡的倒影,将真实的幻想乡封印了。任何人都无法进入真实的幻想乡了,但是她给前来救她的魏潇承留了一个线索。

    她设置了一棵树(有根)。树的每一条边上具有割掉该边的代价。

    魏潇承需要计算出割开这棵树的最小代价,这就是冴月麟和魏潇承约定的小秘密。

    帮帮魏潇承吧。

    注:所谓割开一棵有根树,就是删除若干条边,使得任何任何叶子节点和根节点不连通。


    输入输出格式

    输入格式: 

    输入第一行两个整数n,S表示树的节点个数和根。

    接下来n-1行每行三个整数a、b、c,表示a、b之间有一条代价为c的边。

    输出格式:

    输出包含一行,一个整数,表示所求最小代价。


    输入输出样例

    输入样例#1:
    4 1
    1 2 1 
    1 3 1
    1 4 1
    输出样例#1:
    3
    输入样例#2:
    4 1
    1 2 3
    2 3 1
    3 4 2
    输出样例#2:
    1

    说明

    对于20%的数据,n <= 10

    对于50%的数据,n <= 1000

    对于100%的数据,n <= 100000


    这个题太可怕了,还是普及组的题目...x
    dp比暴力还好想.暴力是我过后看题解后才发现可以这样做的x
    我们用dp[i]表示让i以及以i为根节点的子树合法所要的最小贡献.
    特殊的,每一个叶子节点的权值为INT
    暴力转移qwq
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int maxn=100000+2333;
    const int INT=1e9+7;
    inline int read(){
        int an=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while('0'<=ch&&ch<='9'){an=an*10+ch-'0';ch=getchar();}
        return an*f;
    }
    int f[maxn],cnt;
    int dp[maxn];
    bool vis[maxn];
    struct saber{
    int nex,to,wi;
    }b[maxn<<1];
    int root,n,in[maxn];
    inline void add(int x,int y,int z){
        cnt++;
        b[cnt].to=y;
        b[cnt].nex=f[x];
        b[cnt].wi=z;
        f[x]=cnt;
    }
    void dfs(int x){
        vis[x]=1;
        if(in[x]!=1)dp[x]=0;
        for(int i=f[x];i;i=b[i].nex){
            int v=b[i].to;
            if(!vis[v]){
            dfs(v);
            dp[x]+=min(dp[v],b[i].wi);
            }
        }
    }
    int main(){
        n=read();root=read();
        for(int i=1;i<n;i++){
            int x=read(),y=read(),z=read();
            add(x,y,z);
            add(y,x,z);
            in[x]++;in[y]++;
        }
        for(int i=1;i<=n;++i)dp[i]=INT;
        dp[root]=0;
        dfs(root);
        cout<<dp[root];
        return 0;
    }
    一道难题 Tree

    by:s_a_b_e_r

  • 相关阅读:
    zabbix 配置发送邮件报警
    sql server 修改表结构语法大全
    SQL Server日期与字符串之间的转换
    Convert.ToDateTime(值),方法可以把一个值转化成DateTime类型。
    Oracle trunc()函数的用法
    Oracle job procedure 存储过程定时任务
    向数据库中插入一个DateTime类型的数据到一个Date类型的字段中,需要转换类型。TO_DATE('{0}','YYYY-MM-DD'))
    逗号分隔的字符串转换为行数据(collection)(续)
    Oracle中INSTR、SUBSTR和NVL的用法
    oracle中substr() instr() 用法
  • 原文地址:https://www.cnblogs.com/ck666/p/7635821.html
Copyright © 2011-2022 走看看