首页 > 其他分享 >[题解]P1629 邮递员送信

[题解]P1629 邮递员送信

时间:2024-04-14 18:13:34浏览次数:27  
标签:int 题解 dijkstra Dijkstra 邮递员 push P1629 节点 dis

好久不写图论题了,Dijkstra都花了好长时间捡起来……之前也没有接触过反图的概念。这个题算是我重拾图论知识以来的第一题了。__φ(..)

P1629 邮递员送信

Dijkstra是单源最短路的算法。但这个题除了要求节点\(1\)到其他节点的距离,还要知道其他节点回到节点\(1\)的距离。如果我们每个点都跑一遍Dijkstra,时间复杂度是\(O(n(n \log n+m))\),即使用堆优化也会超时。怎么解决呢?

我们可以额外建一个图,和原图相同,只不过所有边都反向了(原图的反图)。这样从\(1\)开始跑一遍单源最短路,其他节点回到\(1\)的距离就算出来了!

为了方便操作,我们把两个图存在一起,反图节点从\(n+1\)开始存。这里使用邻接表,注意存边的\(G\)数组、距离\(dis\)数组都要开\(2\)倍大小。从\(1\)和\(n+1\)各跑一次Dijkstra,最后把所有距离相加就是结果了。总时间复杂度\(O(n \log n+m)\)。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
struct edge{
	int to,w;
};
vector<edge> G[2010];
int n,m,dis[2020];
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> q;
void dijkstra(int start){
	q.push({0,start});
	dis[start]=0;
	while(!q.empty()){
		auto p=q.top();
		int v=p.second;
		q.pop();
		int len=G[v].size();
		for(int i=0;i<len;i++){
			edge e=G[v][i];
			if(dis[e.to]>dis[v]+e.w){
				dis[e.to]=dis[v]+e.w;
				q.push({dis[e.to],e.to});
			}
		}
	}
}
int main(){
	memset(dis,127,sizeof dis);
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int a,b,c;
		cin>>a>>b>>c;
		edge e;
		e.to=b,e.w=c;
		G[a].push_back(e);
		e.to=a+n;
		G[b+n].push_back(e);
	}
	dijkstra(1);
	dijkstra(n+1);
	int ans=0;
	for(int i=1;i<=2*n;i++) ans+=dis[i];
	cout<<ans;
	return 0;
}

标签:int,题解,dijkstra,Dijkstra,邮递员,push,P1629,节点,dis
From: https://www.cnblogs.com/Sinktank/p/18134444

相关文章

  • [POI2012] Rendezvous 题解
    众所周知,\(lyh\)是一名压行大师,也是一名\(juruo\),所以他将他繁琐的方法用\(102\)行表现了出来……明显原题为基环内向树森林。首先用并查集计算连通块,不在一个连通块里的答案就是\(-1\-1\)。发现实际上答案就是以环为根节点,求\(lca\)的结果,求完后可以分为两种情况:根......
  • [ABC349] AtCoder Beginner Contest 349 题解
    [ABC349]AtCoderBeginnerContest349题解目录[ABC349]AtCoderBeginnerContest349题解A-ZeroSumGameB-CommencementC-AirportCodeD-DivideIntervalE-WeightedTic-Tac-ToeF-SubsequenceLCMG-PalindromeConstruction总结A-ZeroSumGame零和博弈,......
  • P10289 [GESP样题 八级] 小杨的旅游 题解
    题目简述给定一棵树,节点之间的距离为$1$,树上有$k$个传送门,可以从一个传送门瞬间传送到另一个传送门,有$q$此询问,问$u$和$v$之间的最短距离是多少。题目分析首先考虑没有传送门,我们可以直接求两个点的LCA,再用高度容斥计算即可。如果有传送门,那么有用与不用两种选择,如......
  • 【官方题解】Codeforces Round 939 (Div. 2)
    CodeforcesRoundAyachiNeneSolutions(div.2)A.Nene'sGameIdea:[user:Otomachi_Una]Solution不难发现如果一个人初始位置\(p\geqa_1\),那么必然会在有限次回合当中被踢出。答案即为\(\min(n,a_1-1)\)。B.NeneandtheCardGameIdea:[user:Otomachi_Una]Hint......
  • [暴力题解系列+正经题解]好数
    好数虽然不是13号考的那批人,但是还是扔一个暴力题解在这里。首先数据范围\(n\le10^7\),就算纯粹暴力去做也只是\(O(nlogn)\),也就是直接从1到n去枚举。秉持着暴力就是要优化细节的精神,对题目进行一个分析,发现无论如何,个位数必须是奇数,否则必然不满足条件,那么优化手段就显而易见了......
  • P8741 [蓝桥杯 2021 省 B] 填空问题 题解
    题目传送门试题A:空间【解析】本题考察计算机存储的基础知识,只要掌握空间存储的换算方法,就能够算出答案。【程序】#include<bits/stdc++.h>usingnamespacestd;intmain(){printf("%d\n",256*8/32*1024*1024);return0;}【答案】67108864......
  • P8679 [蓝桥杯 2019 省 B] 填空问题 题解
    题目传送门试题A:组队【解析】本题是一道经典的DFS搜索题,每次对各号位的选手进行DFS,找到各号位上有成绩的选手时再进行进一步搜索即可。【程序】#include<bits/stdc++.h>usingnamespacestd;intteam[20][6];intmax_sum;boolvis[20];voiddfs(intu,intsu......
  • P9686 Judg. 题解
    题目传送门一道简单模拟。这道题最简单的方法就是直接在for循环中判断题目给出状态是否为AC,如果不是则输出当前\(i\)的值,否则就不输出。#include<bits/stdc++.h>usingnamespacestd;constintMAXN=1e5+10;intn;stringa[MAXN];intmain(){ scanf("%......
  • P9517 drink 题解
    题目传送门这道题考场上用的查找做的。先用一个结构体分别表示firstlast,然后进行查找即可,两个for循环分别计算出first和last,最后计算它们的差值。(注意,计算差值时要加1)然后你就会发现一个问题:只有\(90\)分。所以我们来思考一下哪里出现了问题。你会发现:如果全都是......
  • P8741 [蓝桥杯 2021 省 B] 填空问题 题解
    题目传送门试题A:空间【解析】本题考察计算机存储的基础知识,只要掌握空间存储的换算方法,就能够算出答案。【程序】#include<bits/stdc++.h>usingnamespacestd;intmain(){printf("%d\n",256*8/32*1024*1024);return0;}【答案】67108864......