zoukankan      html  css  js  c++  java
  • [蓝桥杯][历届试题]大臣的旅费---------求树的直径

    时间限制: 1Sec 内存限制: 128MB 提交: 35 解决: 8

    题目描述
    很久以前,T王国空前繁荣。为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。 
    为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。 
    J是T国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情。他有一个钱袋,用于存放往来城市间的路费。 
    聪明的J发现,如果不在某个城市停下来修整,在连续行进过程中,他所花的路费与他已走过的距离有关,在走第x千米到第x+1千米这一千米中(x是整数),他花费的路费是x+10这么多。也就是说走1千米花费11,走2千米要花费23。 
    J大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可能花费的路费中最多是多少呢? 

    输入
    输入的第一行包含一个整数n,表示包括首都在内的T王国的城市数 
    城市从1开始依次编号,1号城市为首都。 
    接下来n-1行,描述T国的高速路(T国的高速路一定是n-1条) 
    每行三个整数Pi,  Qi,  Di,表示城市Pi和城市Qi之间有一条高速路,长度为Di千米。 
    输出
    输出一个整数,表示大臣J最多花费的路费是多少。 
    样例输入
    5 
    1  2  2 
    1  3  1 
    2  4  5 
    2  5  4 
    样例输出
    135

    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream> 
    #include<queue>
    #define maxn 10010
    #include<algorithm>
    using namespace std;
    int vis[maxn],n;
    typedef struct Node{
        int next;
        int dis;
    }Node; 
    typedef struct Position{
        int pos,sum;
    }Position;
    vector<Node> graph[maxn]; 
    //Position Start,End;
    int length=0;
    long long money(int dist)
    {
        long long sum = 0;
        for(int i=1;i<=dist;i++)
            sum += i+10;
        return sum;
    }
    int BFS(int s)
    {
        int End=1;
        memset(vis,0,sizeof(vis));
        queue<Position> q;
        Position p;
        p.pos=s; p.sum=0;
        vis[s]=1;
        q.push(p);
        while(!q.empty())
        {
            p=q.front(); q.pop();
            int pos=p.pos,sum=p.sum;
            if(sum>length)
            {
                length=sum;
                End=pos;
            }
            for(int i=0;i<graph[pos].size();i++)
            {
                int next = graph[pos][i].next;
                int dis = graph[pos][i].dis;
                if(!vis[next])
                {
                    vis[next]=1;
                    Position next_position;
                    next_position.pos=next;
                    next_position.sum=sum+dis; 
                    q.push(next_position);
                }
            }
        } 
        return End;
    }
    int main(void)
    {
        cin >> n;
        for(int i=1;i<n;i++)
        {
            int p,q,d;
            cin >> p >> q >> d;
            Node node1,node2;
            node1.next=q;      node1.dis=d;
            node2.next=p;   node2.dis=d;
            graph[p].push_back(node1);
            graph[q].push_back(node2); 
        }
        int End = BFS(1);
        BFS(End);
        //Start.pos=1; Start.sum=0;
        //End.pos=BFS(1); End.sum=0;
        //BFS(End.pos);
        //printf("%d
    ",length);
        printf("%lld",money(length));
        return 0;
    }

     下面一个方法也是可以的,但是对于稀疏的矩阵时间复杂度比较高了,容易时间超限

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #define N 10010
    #define INT 10000000
    using namespace std;
     
    int dist[N][N],sum[N],vis[N],n;
    int start=1,last=-1,maxLength=0;
    queue<int>q;
     
    int cmp(int a,int b){ return a>b; }
     
    int max(int a,int b)
    {
        return a>b?a:b;
    }
     
    int money(int dist)
    {
        int sum = 0;
        for(int i=1;i<=dist;i++)
            sum += i+10;
        return sum;
    }
     
    void BFS(int start)
    {
        memset(vis,0,sizeof(vis));
        vis[start]=1;
        while(!q.empty()) q.pop();
        q.push(start);
        while(!q.empty())
        {
            int parent = q.front(); q.pop();
            if(sum[parent]>maxLength) 
            {
                last = parent;
                maxLength = sum[parent];
            }
            for(int son=1;son<=n;son++)
            {
                if(!vis[son] && dist[parent][son]!=0)
                {
                    vis[son] = true;
                    sum[son] = sum[parent]+dist[parent][son];
                    q.push(son);
                }
            }
        }  
    }
     
    int main(void)
    {
         
        scanf("%d",&n);
        /*
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                dist[i][j]=INT;
        */     
        for(int i=1;i<n;i++)
        {
            int begin,End,s;
            scanf("%d%d%d",&begin,&End,&s);
            if(dist[begin][End]<s || dist[begin][End]==INT) 
                dist[begin][End]=dist[End][begin]=s;
        }
         
        BFS(start);
        sum[last]=0;
        BFS(last);
         
        printf("%d
    ",money(maxLength));
    }
  • 相关阅读:
    Codevs 2296 仪仗队 2008年省队选拔赛山东
    Codevs 1535 封锁阳光大学
    Codevs 1069 关押罪犯 2010年NOIP全国联赛提高组
    Codevs 1218 疫情控制 2012年NOIP全国联赛提高组
    Codevs 1684 垃圾陷阱
    洛谷 P1108 低价购买
    Vijos P1325桐桐的糖果计划
    Codevs 3289 花匠 2013年NOIP全国联赛提高组
    Codevs 2611 观光旅游(floyed最小环)
    C语言基础之彩色版C语言(内含linux)
  • 原文地址:https://www.cnblogs.com/zuimeiyujianni/p/8729491.html
Copyright © 2011-2022 走看看