第十二次CCF软件能力认证D题-行车路线 题型:最短路

11 阅读1分钟

3255. 行车路线 - AcWing题库

#include<bits/stdc++.h>
using namespace std;
const int N = 510, M = 200010,INF=1e6;
int n, m;
int h[N], f[M], e[M],w[M], ne[M], idx;
bool st[N][N];
int dist[N][N];

struct Node
{
	int x, y, v;   //点的编号  最后一条小路的长度   距离
	bool operator < (const Node& t)const
	{
		return v > t.v;
	}
		
};
void dijkstra()
{
	priority_queue<Node>heap;
	memset(dist,0x3f,sizeof dist);

	heap.push({1,0,0});  //第一个点前面没有小路
	dist[1][0] = 0;

	while (heap.size())
	{
		auto t = heap.top();
		heap.pop();
		
		if (st[t.x][t.y])continue;  //遍历过的不再遍历
		for (int i = h[t.x]; i != -1; i = ne[i])
		{
			int x = e[i], y = t.y;
			if (f[i])  //如果当前边是小路的话
			{
				y += w[i];
				if (y <= 1000)
				{
					if (dist[x][y] > t.v - t.y * t.y + y * y)
					{
						dist[x][y] = t.v - t.y * t.y + y * y;
						if (dist[x][y] <= INF)
							heap.push({x,y,dist[x][y]});
					}
				}
			}
			else   //大路
			{
				if (dist[x][0] > t.v + w[i])
				{
					dist[x][0] = t.v + w[i];
						if (dist[x][0] <= INF)
							heap.push({x,0,dist[x][0]});
				}
 			}
		}
	}
}

void add(int t, int a, int b, int c)
{
	e[idx] = b, f[idx] = t, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}

int main()
{
	cin >> n >> m;
	memset(h,-1,sizeof h);
	while (m--)
	{
		int t, a, b, c; cin >> t >> a >> b >> c;
		add(t,a,b,c), add(t,b,a,c);
	}
	dijkstra();

	int res = INF;
	for (int i = 0; i < 1000; i++) res = min(res,dist[n][i]);
	cout << res << endl;
	return 0;
}