【P2349 金字塔】题解

题目链接

观察数据范围发现边权都小于255,所以我们可以枚举最大边权。

对于每个最大边权,我们都在不大于这个边权的剩下的边里跑一次最短路。

最后再用最短路求出的答案+所枚举的最大边权=在这个最大边权下的答案。

Code

// Problem: P2349 金字塔
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2349
// Memory Limit: 128 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
#define M 2010
//#define mo
#define N 110
struct node
{
	int x, y, z, n; 
}d[2*M]; 
int n, m, i, j, k; 
int sum=0x3f3f3f3f3f3f3f3f; 
int h[N], ans[N], c[N]; 
int u, v, w, g; 
queue<int>q; 

int spfa(int mx)
{
	while(!q.empty()) q.pop(); 
	memset(ans, 0x3f, sizeof(ans)); 
	ans[1]=0; q.push(1); 
	while(!q.empty())
	{
		u=q.front(); q.pop(); 
		c[u]=0; 
		for(g=h[u]; g; g=d[g].n)
		{
			v=d[g].y; w=d[g].z; 
			if(w>mx) continue; 
			if(ans[u]+w<ans[v])
			{
				ans[v]=ans[u]+w; 
				if(!c[v]) q.push(v), c[v]=1; 
			}
		}
	}
	return ans[n]; 
}

void cun(int x, int y, int z)
{
	d[++k].x=x; d[k].y=y; d[k].z=z; 
	d[k].n=h[x]; h[x]=k; 
}

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read(); m=read(); 
	for(i=1; i<=m; ++i)
	{
		u=read(); v=read(); w=read(); 
		cun(u, v, w); cun(v, u, w); 
	}
	for(i=3; i<=256; ++i) sum=min(sum, spfa(i)+i);  
	printf("%lld", sum); 
	return 0; 
}

posted @ 2021-11-18 21:58  zhangtingxi  阅读(137)  评论(0编辑  收藏  举报