大臣的旅費 連通塊【藍橋真題】(c++)

試題 大臣的旅費

題述

資源限制
時間限制:1.0s 內存限制:256.0MB
問題描述
很久以前,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
輸出格式
大臣J從城市4到城市5要花費135的路費。

我的思路

算法一覽

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <string.h>
#define inf 0x3f3f3f3f
 
using namespace std;
 
typedef long long ll;
const int maxn = 1000000;
int head[maxn],cnt,vis[maxn];
ll dist;
struct Edge{
    int v,nex;
    ll w;
}edge[maxn*2];

typedef struct Node {
    int x;
    ll dis;
}node;

void addEdge(int u,int v,ll w) {
    edge[cnt].v = v;
    edge[cnt].w = w;
    edge[cnt].nex = head[u];
    head[u] = cnt++;
 
    edge[cnt].v = u;
    edge[cnt].w = w;
    edge[cnt].nex = head[v];
    head[v] = cnt++;
}

int bfs(int Start) {
    int source;
    node cur,nex;
    memset(vis,0,sizeof(vis));
    queue<node>qu;
    cur.x = Start;
    cur.dis = 0;
    vis[Start] = 1;
    qu.push(cur);
    dist = 0;
    source = Start;
    int a,b;
    while(!qu.empty()) {
        cur = qu.front();
        qu.pop();
        a = cur.x;
        if(cur.dis > dist) {
            dist = cur.dis;
            source = a;
        }
        int i;
        for(i=head[a]; i!=-1; i=edge[i].nex) {
            b = edge[i].v;
            if(vis[b]==0) {
                vis[b] = 1;
                nex.x = b;
                nex.dis = cur.dis + edge[i].w;
                qu.push(nex);
            }
        }
    }
    return source;
}

int main() {
    int n,u,v;
    ll w;
    //~指的是按位取反,下句 ~scanf("%d",&n)等同於將scanf("%d",&n)!=-1,即輸入出錯時返回。 
    while(~scanf("%d",&n)) {
        cnt = 0;
        memset(head,-1,sizeof(head));//分配內存 
        for(int i = 1; i < n; i++) {
            scanf("%d%d%lld",&u,&v,&w);
            addEdge(u,v,w);
        }
        int newStart = bfs(1); //可以選圖中任意點爲起點,在此我選擇1
        bfs(newStart);         //從距1最遠的點newStart開始找離newStart最遠的點。
        ll ans;
        //可以按照等差數列公式直接求解答案。
        if(dist%2==0) {
            ans = dist/2;
            ans = ans*(dist+1);
        }
        else {
            ans = (dist+1)/2;
            ans = ans*dist;
        }
        ans += dist*10;
        printf("%lld\n",ans);
    }
    return 0;
}

上文鏈接:最大比例 公約數複用 【藍橋真題】 (c++)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章