洛谷 P4822 [BJWC2012]冻结

题目传送门

分层图最短路,和另一题几乎一样,唯一区别在于这道题是讲路径减半.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>

using namespace std;

int n,m,k,head[51],dis[51][51],tot,ans = 2099999999;
bool vis[51][51];
struct node {
	int to,v,step;
	bool operator <(const node &s) const {
		return v > s.v;
	}
};
priority_queue<node> q;
struct kkk {
	int to,v,next;
}e[5001];

inline node dp(int cs,int d) {//此dp仅为一个名字 
	node p;
	p.step = cs;
	p.to = d;
	p.v = dis[cs][d];
	return p;
}

inline void spfa() {
	memset(dis,0x3f,sizeof(dis));
	dis[0][1] = 0;
	q.push(dp(0,1));
	while(!q.empty()) {
		node w = q.top();
		q.pop();
		if(vis[w.step][w.to]) continue;
		vis[0][1] = 1;
		for(int i = head[w.to];i; i = e[i].next) {
			int u = e[i].to;
			if(dis[w.step][w.to] + e[i].v < dis[w.step][u]) {
				dis[w.step][u] = dis[w.step][w.to] + e[i].v;
				q.push(dp(w.step,u));
			}
			if(dis[w.step+1][u] > dis[w.step][w.to] + e[i].v / 2 && w.step < k) {
				dis[w.step+1][u] = dis[w.step][w.to] + e[i].v / 2;
				q.push(dp(w.step+1,u));
			}
		}
	}
}

inline void add(int x,int y,int z) {
	e[++tot].to = y;
	e[tot].v = z;
	e[tot].next = head[x];
	head[x] = tot;
}

int main() {
	scanf("%d%d%d",&n,&m,&k);
	for(int i = 1;i <= m; i++) {
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		add(x,y,z);
		add(y,x,z);
	}
	spfa();
	for(int i = 0;i <= k; i++)
		ans = min(ans,dis[i][n]);
	printf("%d",ans);
	return 0;
} 
posted @ 2020-10-23 21:45  Mr^Simon  阅读(55)  评论(0编辑  收藏  举报