# Shortest Path on a Line (最短路变体)

题目链接 :https://nikkei2019-2-qual.contest.atcoder.jp/tasks/nikkei2019_2_qual_d

D - Shortest Path on a Line


Time limit : 2sec / Memory limit : 1024MB

Score : 600 points

Problem Statement

We have N points numbered 1 to N arranged in a line in this order.

Takahashi decides to make an undirected graph, using these points as the vertices. In the beginning, the graph has no edge. Takahashi will do M operations to add edges in this graph. The i-th operation is as follows:

  • The operation uses integers Li and Ri between 1 and N (inclusive), and a positive integer Ci. For every pair of integers (s,t) such that Lis<tRi, add an edge of length Ci between Vertex s and Vertex t.

The integers L1,…,LMR1,…,RMC1,…,CM are all given as input.

Takahashi wants to solve the shortest path problem in the final graph obtained. Find the length of the shortest path from Vertex 1 to Vertex N in the final graph.

Constraints

  • 2≤N≤105
  • 1≤M≤105
  • 1≤Li<RiN
  • 1≤Ci≤109

Input

Input is given from Standard Input in the following format:

N M
L1 R1 C1
:
LM RM CM

Output

Print the length of the shortest path from Vertex 1 to Vertex N in the final graph. If there is no shortest path, print -1 instead.


Sample Input 1

Copy

4 3
1 3 2
2 4 3
1 4 6

Sample Output 1

Copy

5

We have an edge of length 2 between Vertex 1 and Vertex 2, and an edge of length 3 between Vertex 2 and Vertex 4, so there is a path of length 5 between Vertex 1 and Vertex 4.


Sample Input 2

Copy

4 2
1 2 1
3 4 2

Sample Output 2

Copy

-1

Sample Input 3

Copy

10 7
1 5 18
3 4 8
1 3 5
4 7 10
5 9 8
6 10 5
8 10 3

Sample Output 3

Copy

28

题目大意 :

输入N个点, M次操作, 每次操作输入 L, R, W, 表示从L 到 L + 1, L + 2 …… R 每个点都有一条权值为W的无向边,输出1 到 N的最短路

思路 :

普通建边肯定超时, 正好以前做过类似的题,由那道题得到了一些启发。首先通过观察可以发现,1到每个点的最短路, 一定只会随着编号增加而增加,不会减少,那么无向边就没用了,既然只会增,换句话说不会往前跑,建一条边就行,其次是对于每个L 到 R, 你不知道经过之间的哪个点, 所以可以对每个点往前一个编号建一条权值为0的边, 这样问题就解决了

Accepted code 

#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define sc scanf
#define ls rt << 1
#define rs ls | 1
#define Min(x, y) x = min(x, y)
#define Max(x, y) x = max(x, y)
#define ALL(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define MEM(x, b) memset(x, b, sizeof(x))
#define lowbit(x) ((x) & -(x))
#define P2(x) ((x) * (x))

typedef long long ll;
const int MOD = 1e9 + 7;
const int MAXN = 2e5 + 100;
const ll INF = 0x3f3f3f3f3f3f3f3f;
inline ll fpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % MOD; b >>= 1; t = (t*t) % MOD; }return r; }

struct Edge
{
	ll v, w;
};
struct node
{
	ll id, w;
	bool operator < (const node &oth) const
	{
		return w > oth.w;
	}
}mid;
vector <Edge> e[MAXN << 1];
ll dis[MAXN], n, m;
bool vis[MAXN];
void dijkstra(int x) {
	priority_queue <node> q;
	MEM(dis, INF);
	q.push({ x, 0 }); dis[x] = 0;
	while (!q.empty()) {
		mid = q.top(); q.pop();
		ll ans = mid.id;
		if (vis[ans]) continue; 
		vis[ans] = true;
		for (auto it : e[ans]) {
			ll vi = it.v, wi = it.w;
			if (dis[vi] > dis[ans] + wi) {
				dis[vi] = dis[ans] + wi;
				q.push({ vi, dis[vi] });
			}
		}
	}
}

int main()
{
	cin >> n >> m;
	for (ll i = 2; i <= n; i++) e[i].push_back({ i - 1, 0 }); // 往前走
	for (ll i = 0; i < m; i++) {
		ll ui, vi, wi; sc("%lld %lld %lld", &ui, &vi, &wi); 
		e[ui].push_back({ vi, wi });
	}
	dijkstra(1);
	if (dis[n] == INF) printf("-1\n");
	else printf("%lld\n", dis[n]);
	return 0;  // 改数组大小!!!
}
发布了213 篇原创文章 · 获赞 264 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43851525/article/details/103517857