2019 ACM-ICPC 全国邀请赛(陕西西安) M.Travel

1 篇文章 0 订阅
1 篇文章 0 订阅

M.Travel

题目链接: https://nanti.jisuanke.com/t/39280

Problem Description

There are n n n planets in the MOT galaxy, and each planet has a unique number from 1 ∼ n 1∼n 1n. Each planet is connected to other planets through some transmission channels. There are m m m transmission channels in the galaxy. Each transmission channel connects two different planets, and each transmission channel has a length.
The residents of the galaxy complete the interplanetary voyage by spaceship. Each spaceship has a level. The spacecraft can be upgraded several times. It can only be upgraded 1 1 1 level each time, and the cost is c c c. Each upgrade will increase the transmission distance by d d d and the number of transmissions channels by e e e to the spacecraft. The spacecraft can only pass through channels that are shorter than or equal to its transmission distance. If the number of transmissions is exhausted, the spacecraft can no longer be used.
Alice initially has a 0 0 0-level spacecraft with transmission distance of 0 0 0 and transmission number of 0 0 0. Alice wants to know how much it costs at least, in order to transfer from planet 1 1 1 to planet n n n.

Input

Each test file contains a single test case. In each test file:
The first line contains n , m , n, m, n,m, indicating the number of plants and the number of transmission channels.
The second line contains c , d , e , c, d, e, c,d,e, representing the cost, the increased transmission distance, and the increased number of transmissions channels of each upgrade, respectively.
Next m m m lines, each line contains u , v , w , u,v,w, u,v,w, meaning that there is a transmission channel between u u u and v v v with a length of w w w. ( 2 ≤ n ≤ 1 0 5 , n − 1 ≤ m ≤ 1 0 5 , 1 ≤ u , v ≤ n , 1 ≤ c , d , e , w ≤ 1 0 5 ) (2≤n≤10^5, n-1≤m≤10^5,1≤u,v≤n ,1≤c,d,e,w≤10^5) (2n105,n1m105,1u,vn,1c,d,e,w105)
(The graph has no self-loop , no repeated edges , and is connected)

Output

Output a line for the minimum cost. Output − 1 -1 1 if she can’t reach.

Sample Input

5 7
1 1 1
1 2 1
1 3 5
1 4 1
2 3 2
2 4 5
3 4 3
3 5 5

Sample Output

5

题意

n n n个点,编号从 1 1 1 n n n,有 m m m条边,每条边有一个长度 w w w
A l i c e Alice Alice有一艘飞船, A l i c e Alice Alice可以给它升级很多次(无限),每升级一次需要花费 c c c,升级一次之后飞船单次可飞行距离增加 d d d,可飞行次数增加 e e e。如果飞船需要飞过一条边,就需要满足单次可飞行距离 ≥ ≥ 这条路的长度同时可飞行次数不为 0 0 0
现在 A l i c e Alice Alice在编号为 1 1 1的点,她的飞船为 0 0 0级,单次可飞行距离和可飞行次数都为 0 0 0,请你求出最小的花费使得 A l i c e Alice Alice可以到达 n n n点,如果不能到达 n n n则输出 − 1 -1 1
输入保证图联通,没有自环,没有重边。

思路

菜是原罪,人生第一次 i c p c icpc icpc因为我这题没写出来带着队友打铁了,赛后看了一下大佬的思路才会的。
观察输入数据的数据范围可以知道最多有 1 ∗ 1 0 5 1*10^5 1105条边,边的长度最长也就是 1 ∗ 1 0 5 1*10^5 1105,这也就说明最多升级 1 ∗ 1 0 5 1*10^5 1105次是肯定够的,又因为是联通图,所以输出 − 1 -1 1的情况是不存在的,因为可以无限次升级,怎么样都能到达 n n n点,就是花费的问题。
那么我们就可以对升级次数进行二分,然后 b f s bfs bfs走一遍看看能不能到达 n n n点,如果当前的升级次数可以到达 n n n则更新最小的升级次数,最后输出 c c c*最小升级次数就 o k ok ok了。
最后记得用 l o n g   l o n g long\ long long long,不然会爆 i n t int int导致 w a wa wa

代码

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long
#define pi acos(-1.0)

using namespace std;

typedef struct{//存边的结构体
	ll v, len;//入点编号,边的长度 
} node;

typedef struct{//bfs结点
	ll num, cnt;//当前点编号,可走边的次数 
} nodee;

const ll N = 1e5+5;
ll n, m, c, d, e, res = 0;
ll u, v, len, l = 0, r = N, vis[N];
vector<node> vec[N];

bool bfs(ll mid){
	ll dd = mid*d;//单次飞行最大可飞行距离 
	queue<nodee> que;
	memset(vis, 0, sizeof(vis));//初始化标记数组
	vis[1] = 1; //标记
	que.push((nodee){1, mid*e});//从1开始,还有mid*e次移动机会 
	while (que.size()){
		nodee nn = que.front(); que.pop();
		ll u = nn.num;
		if (u == n){//升级mid次可以到达n 
			return true;//成功
		}
		else{
			for (ll i = 0; i < vec[u].size(); i++){//遍历子节点 
				ll v = vec[u][i].v, dis = vec[u][i].len;
				if (!vis[v] && nn.cnt>0 && dd>=dis){//没去过v && 还可以移动 && 可以跳过去 
					vis[v] = 1;//标记,后面这个点就不用再来了
					que.push((nodee){v, nn.cnt-1});//次数减一 
				}
			}	
		}
	}
	return false;//失败
}

int main(){
	scanf("%lld%lld", &n, &m);
	scanf("%lld%lld%lld", &c, &d, &e);
	while (m--){
		scanf("%lld%lld%lld", &u, &v, &len);
		vec[u].push_back((node){v, len});//加边 
		vec[v].push_back((node){u, len});
	}
	while (l <= r){//二分升级次数 
		ll mid = (l+r)/2;
		if (bfs(mid)){//如果可行 
			res = mid;
			r = mid-1;//向更小的升级次数试探 
		}
		else{
			l = mid+1;//向更大的升级次数试探 
		}
	}
	printf("%lld\n", c*res);
	
	return 0;
} 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值