您的位置:首页 > 其它

CCF-201503-5 最小花费

2016-09-04 21:39 393 查看

问题描述

  C国共有n个城市。有n-1条双向道路,每条道路连接两个城市,任意两个城市之间能互相到达。小R来到C国旅行,他共规划了m条旅行的路线,第i条旅行路线的起点是si,终点是ti。在旅行过程中,小R每行走一单位长度的路需要吃一单位的食物。C国的食物只能在各个城市中买到,而且不同城市的食物价格可能不同。

  然而,小R不希望在旅行中为了购买较低价的粮食而绕远路,因此他总会选择最近的路走。现在,请你计算小R规划的每条旅行路线的最小花费是多少。

输入格式

  第一行包含2个整数n和m。

  第二行包含n个整数。第i个整数wi表示城市i的食物价格。

  接下来n-1行,每行包括3个整数u, v, e,表示城市u和城市v之间有一条长为e的双向道路。

  接下来m行,每行包含2个整数si和ti,分别表示一条旅行路线的起点和终点。

输出格式

  输出m行,分别代表每一条旅行方案的最小花费。

样例输入

6 4

1 7 3 2 5 6

1 2 4

1 3 5

2 4 1

3 5 2

3 6 1

2 5

4 6

6 4

5 6

样例输出

35

16

26

13

样例说明

  对于第一条路线,小R会经过2->1->3->5。其中在城市2处以7的价格购买4单位粮食,到城市1时全部吃完,并用1的价格购买7单位粮食,然后到达终点。

评测用例规模与约定

  前10%的评测用例满足:n, m ≤ 20, wi ≤ 20;

  前30%的评测用例满足:n, m ≤ 200;

  另有40%的评测用例满足:一个城市至多与其它两个城市相连。

  所有评测用例都满足:1 ≤ n, m ≤ 105,1 ≤ wi ≤ 106,1 ≤ e ≤ 10000。

题解

蒟蒻只会暴力搞,30分飘过..

等get了新技能,再来填坑..

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

typedef pair<int, int> Pii;
typedef long long LL;
const int maxn = 100000 + 5;
const int inf  = 0x3f3f3f3f;
int n, m;
int price[maxn];
vector<Pii> G[maxn];

struct node{
int u, price, len;
node(int u, int p, int l):u(u), price(p), len(l){}
};
vector<node> path;
bool vis[maxn];

void dfs(int s, int t){
if(s == t){
//        for(int i = 0; i < path.size(); ++i){
//            //printf("(%d, %d, %d) ", path[i].u, path[i].price, path[i].len);
//            cout << path[i].u << " ";
//        }
//        cout << endl;

LL ans = 0;
int minPrice = path[0].price;;
for(int i = 1; i < path.size(); ++i){
if(minPrice <= path[i].price){
ans += (LL)minPrice * path[i].len;
}
else{
ans += (LL)minPrice * path[i].len;
minPrice = path[i].price;
}
}

cout << ans << endl;
return;
}

vis[s] = true;
for(int i = 0; i < G[s].size(); ++i){
int u = G[s][i].first, p = G[s][i].second;
if(!vis[u]){
vis[u] = true;
path.push_back(node(u, price[u], p));
dfs(u, t);
}
}

path.pop_back();
}

void solve(int s, int t){
path.clear();
memset(vis, false, sizeof(vis));
path.push_back(node(s, price[s], inf));
dfs(s, t);
}

int main(){
#ifdef LOCAL
freopen("data.in", "r", stdin);
#endif // LOCAL

cin >> n >> m;
for(int i = 1; i <= n; ++i) scanf("%d", price + i);
for(int i = 0; i < n - 1; ++i){
int u, v, e;
scanf("%d %d %d", &u, &v, &e);
G[u].push_back(Pii{v, e});
G[v].push_back(Pii{u, e});
}

for(int i = 0; i < m; ++i){
int s, t;
scanf("%d %d", &s, &t);
solve(s, t);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ccf 图论