[LG] P4822 [BJWC2012] 冻结

题意:有K次机会使一条边权减半的情况下,做最短路

k<=n<=50, M<=1e3,

有干扰的最短路,可以用分层图最短路做

分k层,层内正常连接,下层到上层连单向边

统计答案在n的k层内取min即可!

#include<bits/stdc++.h>

using namespace std;

inline int rd(){
	int ret=0,f=1;char c;
	while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
	while(isdigit(c))ret=ret*10+c-'0',c=getchar();
	return ret*f;
}

const int M = 800001;
const int MAXN = 25001;
struct Edge{
	int next,to,w;
}e[M<<1];
int ecnt,head[MAXN];
inline void add(int x,int y,int w){
	e[++ecnt].next = head[x];
	e[ecnt].to = y;
	e[ecnt].w = w;
	head[x] = ecnt;
	// cout<<"ADD:"<<x<<" "<<y<<" "<<w<<endl;
}

struct Node{
	int id,w;
	Node(int x=0,int y=0){id=x;w=y;}
	bool operator < (const Node &rhs) const {
		return w>rhs.w;
	}
}top;
priority_queue<Node> Q;
int dis[MAXN],vis[MAXN];
void dij(int st){
	memset(dis,0x3f,sizeof(dis));
	dis[st]=0;
	Q.push(Node(st,0));
	while(!Q.empty()){
		top=Q.top();Q.pop();
		int mnid=top.id,mn=top.w;
		if(vis[mnid]) continue;
		if(mn!=dis[mnid]) continue;
		for(int i=head[mnid];i;i=e[i].next){
			int v=e[i].to;
			if(dis[v]>mn+e[i].w){
				dis[v]=mn+e[i].w;
				Q.push(Node(v,dis[v]));
			}
		}
	}
}
int n,m,k;

int flo(int x,int y){
	return y*n+x;
}

int main(){
	n=rd();m=rd();k=rd();
	int x,y,w;
	for(int i=1;i<=m;i++){
		x=rd();y=rd();w=rd();
		for(int j=0;j<=k;j++){
			add(flo(x,j),flo(y,j),w);
			add(flo(y,j),flo(x,j),w);
			if(j==k) continue;
			add(flo(x,j),flo(y,j+1),w>>1);
			add(flo(y,j),flo(x,j+1),w>>1);
		}
	}
	dij(1);
	int ans=1e9;
	for(int i=0;i<=k;i++){
		ans=min(ans,dis[flo(n,i)]);
	}
	cout<<ans;
	return 0;
}
posted @ 2020-08-02 11:33  GhostCai  阅读(69)  评论(0编辑  收藏  举报