J.是时候表演真正的技术了---优化dijkstra的多起点压缩

是时候表演真正的技术了

Time Limit 1000MS
Memory Limit 256MB

题目链接https://csustacm.fun/problem/1097
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


emmm,首先想到的就是暴力。。。直接每个点跑一遍最短路看看它们到哪个宝藏最近。即使经过优化之后也是n2log(n)的复杂的,直接T。

稍微好一点的就是将每个宝藏跑一遍最短路然后每个点取最小值。复杂度还是很高会T,不过当时LJ大佬就是用这种方法的,T了之后努力剪枝然后,就A了。。。神TM一般的剪枝。。。。

接下来就是一般的正解了,我们直接将所有宝藏的坐标压如队列就好了,这样我们只要跑一遍最短路用优化dj跑的话就是nlog(n),1e5的数据随便过

以下是AC代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int mac=1e5+10;
const ll inf=1e16+7;
int vis[mac];
ll dis[mac];
struct node 
{
	ll to,cost;
};
struct node1
{
	int id;
	ll s;
	bool friend operator <(node1 a,node1 b){
		return a.s>b.s;
	}
};
vector<node>g[mac];
int n;
void dj();
int main()
{
	int m,k,x;
	scanf ("%d%d%d",&n,&m,&k);
	for (int i=1; i<=n; i++) dis[i]=inf; 
	for (int i=1; i<=k; i++){
		scanf ("%d",&x);
		dis[x]=0;
	}
	int u,v,w;
	for (int i=1; i<=m; i++){
		scanf ("%d%d%d",&u,&v,&w);
		node s;
		s.to=v; s.cost=w;
		g[u].push_back(s);
		s.to=u;
		g[v].push_back(s);
	}
	int q;
	dj();
	scanf ("%d",&q);
	while (q--){
		scanf ("%d",&x);
		printf ("%lld\n",dis[x]);
	}
	return 0;
}
void dj()
{
	priority_queue<node1>q;
	for (int i=1; i<=n; i++){
		node1 w;
		if (!dis[i]){
			w.id=i; w.s=0;
			q.push(w);
		}
	}
	while (!q.empty()){
		node1 rs=q.top();
		q.pop();
		int now=rs.id;
		if (vis[now]) continue;
		vis[now]=1;
		for (int i=0; i<g[now].size(); i++){
			if (dis[now]+g[now][i].cost<dis[g[now][i].to]){
				dis[g[now][i].to]=dis[now]+g[now][i].cost;
				node1 we;
				we.id=g[now][i].to;
				we.s=dis[g[now][i].to];
				q.push(we);
			}
		}	
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值