最短路 Dijkstra ACM-ICPC 2018 南京赛区网络预赛 K Magical Girl Haze

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/DADDY_HONG/article/details/82291706

K Magical Girl Haze

There are N cities in the country, and M directional roads from u to v(1≤u,v≤n). Every road has a distance ci​. Haze is a Magical Girl that lives in City 1, she can choose no more than K roads and make their distances become 0. Now she wants to go to City N, please help her calculate the minimum distance.

Input

The first line has one integer T(1≤T≤5), then following T cases.

For each test case, the first line has three integers N, M and K.

Then the following M lines each line has three integers, describe a road, Ui​,Vi​,Ci​. There might be multiple edges between u and v.

It is guaranteed that N≤100000,M≤200000,K≤10,
0≤Ci​≤1e9. There is at least one path between City 1 and City N.

Output

For each test case, print the minimum distance.

样例输入

1
5 6 1
1 2 2
1 3 4
2 4 3
3 4 1
3 5 6
4 5 2

样例输出

3

题目来源

ACM-ICPC 2018 南京赛区网络预赛

题目大意:haze要从城市1走到城市n,她可以使最多k条路的路长变为0,问她至少要走多少距离。

最短路问题,因为k<=10,所以考虑可以将d数组开成二位进行最短路算法:

嘛要用堆优化(优先队列),3个状态转移/更新  1到v有最多j条路化为0  的最小值:

d[v][j]=min(d[v][j],d[u][j-1]);    //1到u有最多j-1条路化为0,u-v化为0
d[v][j]=min(d[v][j],d[v][j-1]);    //1到v有最多j条路化为0,最多有j-1条路化为0(路的条数<j)
d[v][j]=min(d[v][j],d[u][j]+c);     //1到u有最多j条路化为0,则1到v最多有j条路化为0还要再加上c(u,v)

取其中最小值。

思路清晰+最短路堆优化Dijkstra=AC

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

const int maxn=1e5+10;
const int maxk=11;
const int maxm=2e5+10;
const long long inf=0x3f3f3f3f3f3f;

int n,m,k;
long long d[maxn][maxk];

struct node{
	int v;
	long long c;
	node(int a,long long b):v(a),c(b){}
};

struct p{
	int u,k;
	long long dis;
	p(int a,int b,long long c):u(a),k(b),dis(c){}
	friend bool operator < (p a,p b)
	{
		return a.u>b.u;
	}
};

vector <node> r[maxn];

void dijkstra()
{
	priority_queue <p,vector<p>,less<p> > q;
	for(int i=2;i<=n;++i)
		for(int j=0;j<=k;++j)
			d[i][j]=inf;
	q.push(p(1,0,0));
	while(!q.empty()){
		p now=q.top();
		q.pop();
		int u=now.u;
		int z=now.k;
		if(d[u][z]<now.dis) continue;
		int sz=r[u].size();
		for(int i=0;i<sz;++i){
			int v=r[u][i].v;
			long long c=r[u][i].c;
			for(int j=z;j<=k;++j){
				long long pre=d[v][j];
				if(j) {
					d[v][j]=min(d[v][j],d[u][j-1]);
					d[v][j]=min(d[v][j],d[v][j-1]);
				}
				d[v][j]=min(d[v][j],d[u][j]+c);
				if(d[v][j]<pre) q.push(p(v,j,d[v][j]));
			}
		}
	}
}

int main()
{
	int t;
	int u,v;
	long long c;

	scanf("%d",&t);
	for(int j=0;j<=k;++j)
		d[1][j]=0;
	while(t--){
		scanf("%d%d%d",&n,&m,&k);
		for(int i=1;i<=n;++i)
			r[i].clear();
		for(int i=0;i<m;++i){
			scanf("%d%d%lld",&u,&v,&c);
			r[u].push_back(node(v,c));
		}
		dijkstra();
		printf("%lld\n",d[n][k]);
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/DADDY_HONG/article/details/82291706