zoukankan      html  css  js  c++  java
  • COGS 2095. 不平凡的引线

    2095. 不平凡的引线

    ★☆   输入文件:firelead.in   输出文件:firelead.out   简单对比
    时间限制:1 s   内存限制:256 MB

    【题目描述】

    这里说的引线是炮仗的引线,它可以匀速的燃烧。熊孩子经常会把引线抽出,点引线玩。但是有些熊孩子看到这些并不满足,于是他们把引线的形状摆成一棵树。同时点燃所有的叶子结点,多少单位时间后引线才能燃烧完?可以认为每个单位时间会燃烧一个单位长度的引线。

    如上图共有3条引线,其中(1,2)引线的单位长度为2,(2,3)引线单位长度为1,(2,4)引线单位长度为1。现在同时点燃所有叶子结点(叶子结点 定义为只与一条边相邻的结点,如上图中的叶子结点为1,3,4)。1个单位时间以后,(2,3),(2,4)被完全烧完,(1,2)仅剩一半。这时剩下的 半段(1,2)两头均被引燃,所以再过0.5个单位时间后,(1,2)被完全烧完。共需1.5个单位时间。

    【输入格式】


    第一行一个整数m,表示共有m条引线。

    接下来m行,每行三个整数u,v,len表示有一条引线两端分别是u和v,其长度为len


    【输出格式】

    一个浮点数,表示需要多少单位时间引线会燃烧完,保留一位小数。

    【样例输入】

    3
    1 2 2
    2 3 1
    2 4 1

    【样例输出】

    1.5

    【提示】


    数据范围与约定:

    对于30%的数据:m+1 <= 100,保证引线长度均为1

    对于60%的数据:m+1 <= 1000,保证引线长度均为1

    对于100%的数据:m+1 <= 100000,保证输入的引线一定可以构成一棵树,引线的长度len满足1 <= len <= 10000。

    m条边的节点标号范围从1到m+1

    题解:

      这个题目真的妙不可言,考试的时候只想到模拟。

      好了,这个题目求每条边被烧到的时间非常困难,直接求是n平方的,所以我们考虑先求出每个点被烧到的时间,显然是当前节点到所有节点的最短路,这个取min,这个东西可以一次spfa求出来,只要把所有的点事先加如队列之中求出来的就是i这个节点到每个叶子节点的最短路(取min,并且对于图也一样)。

      然后求出来点的,就可以推公式求边的了,显然答案就是所有条边被烧完的时间取max,然后考虑怎么推,当dis[to]=dis[now]+quan时(now和to是边上的两个节点,权值是边权),时间=dis[now]+quan=(dis[now]+dis[to]+quan)/2;当dis[to]<dis[now]+quan时(令dis[to]>dis[now]),时间=dis[now]+dis[to]-dis[now]+(quan-(dis[to]-dis[now]))/2=(dis[now]+dis[to]+quan)/2。(因为我们是用多源最短路求的dis,所以不存在dis[now]>dis[to]+quan)把公式带进去就可以了。

    代码:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <queue>
    #define MAXN 200100
    using namespace std;
    struct edge{
        int first;
        int next;
        int to;
        int quan;
    }a[MAXN*2];
    int in[MAXN];
    double dis[MAXN];
    bool have[MAXN];
    int m,num=0,n;
    queue<int> q;
    
    void addedge(int from,int to,int quan){
        a[++num].to=to;
        a[num].quan=quan;
        a[num].next=a[from].first;
        a[from].first=num;
    }
    
    void spfa(){
        while(!q.empty()) q.pop();
        memset(dis,127,sizeof(dis));
        for(int i=1;i<=n;i++){
            if(in[i]==1){
                dis[i]=0,q.push(i),have[i]=1;
            }
        }
        while(!q.empty()){
            int now=q.front();
            q.pop();have[now]=0;
            for(int i=a[now].first;i;i=a[i].next){
                int to=a[i].to,quan=a[i].quan;
                if(dis[to]>dis[now]+quan){
                    dis[to]=dis[now]+quan;
                    if(!have[to]){
                        have[to]=1;
                        q.push(to);
                    }
                }
            }
        }
    }
    
    int main()
    {
        scanf("%d",&m);n=m+1;
        for(int i=1;i<=m;i++){
            int x,y,z;scanf("%d%d%d",&x,&y,&z);
            addedge(x,y,z);
            addedge(y,x,z);
            in[x]++;in[y]++;
        }
        spfa();
        double ans=0;
        for(int now=1;now<=n;now++){
            for(int i=a[now].first;i;i=a[i].next){
                int to=a[i].to,quan=a[i].quan;
                double x=(dis[now]+dis[to]+quan)/2.0;
                ans=max(ans,x);
            }
        }
        printf("%0.1f",ans);
        return 0;
    }
  • 相关阅读:
    [Angular] Architectures for Huge Angular Based Enterprise
    [Bash] Move and Copy Files and Folders with Bash
    [Bash] Create nested folder in Bash
    [Bash] View Files and Folders in Bash
    [Angular] Expose Angular Component Logic Using State Reducers
    [Angular] Modify User Provided UI with Angular Content Directives
    [Angular] Refactor Angular Component State Logic into Directives
    [Angular] Communicate Between Components Using Angular Dependency Injection
    [Angular] Write Compound Components with Angular’s ContentChild
    java web从零单排第二十一期《Hibernate》主键的生成方式,用户增加与显示用户列表
  • 原文地址:https://www.cnblogs.com/renjianshige/p/7418865.html
Copyright © 2011-2022 走看看