2019.09.22日常总结兼洛谷P3371和P4779题解

【题意】: 给定 n n n个点和 m m m条边,求起点 s s s到所有点的最短路。

【思路】: 两道题的题意一模一样,但由于数据范围的差异和数据的来源,两题的解法稍有不同,考察了求最短路最经典而快速的两种方法: s p f a spfa spfa算法和带堆优化的 d i j k s t r a dijkstra dijkstra算法(注意“带堆优化”这几个字眼,不带堆优化的 d i j k s t r a dijkstra dijkstra时间复杂度为 O ( n 2 ) O(n^2) O(n2),而带堆优化的 d i j k s t r a dijkstra dijkstra时间复杂度仅为 O ( n × l o g n ) O(n\times logn) O(n×logn))。
在这里,个人推荐在无负边权时用 d i j k s t r a dijkstra dijkstra算法,其它情况用 s p f a spfa spfa算法,甚至在一般情况下都可以用 s p f a spfa spfa算法。

【代码】:
[code of the algorithm spfa(即P3371题题解)]:

//By HPXXZYY
#include 
using namespace std;
const int M=500100;
const int N=100100;
struct node{
	int next,to,w;
}e[M];int h[N],tot;
inline void add_edge(int a,int b,int c){
	e[++tot]=(node){h[a],b,c};h[a]=tot;
}
long long d[N];bool vis[N];
void spfa_algorithm(int s){
	queue<int> q;q.push(s);
	memset(vis,true,sizeof(vis));
	memset(d,127,sizeof(d));
	d[s]=vis[s]=0;
	do{
		int u=q.front();q.pop();vis[u]=true;
		for(int i=h[u];i;i=e[i].next){
			register int v=e[i].to;
			if (d[v]>d[u]+e[i].w){
				d[v]=d[u]+e[i].w;
				if (vis[v]){
					vis[v]=false;
					q.push(v);
				}
			}
		}
	}while (q.size());
}
#define gc getchar()
#define g(c) isdigit(c)
inline int read(){
	char c=0;int x=0;bool f=0;
	while (!g(c)) f=c=='-',c=gc;
	while (g(c)) x=x*10+c-48,c=gc;
	return f?-x:x;
}
int n,m,a,b,i,s;
int main(){
	freopen("t1.in","r",stdin);
	n=read();m=read();s=read();
	for(i=1;i<=m;i++){
		a=read();b=read();
		add_edge(a,b,read());
	}
	spfa_algorithm(s);
	for(i=1;i<=n;i++)
	if (d[i]!=d[0]) printf("%d ",d[i]);
	else printf("2147483647 ");
	return 0;
}

[code of the algorithm dijkstra(即P4779题题解)]:

//By HPXXZYY,too.
#include 
using namespace std;
const int M=200100;
const int N=100100;
struct node{
	int next,to,w;
}e[M];int h[N],tot;
inline void add_edge(int a,int b,int c){
	e[++tot]=(node){h[a],b,c};h[a]=tot;
}
struct data{
	int u,len;
	bool operator < (data c) const{
		return len>c.len;
	}
};
int d[N];
void dijkstra(int s){
	priority_queue<data> q;
	q.push((data){s,0});
//	memset(vis,true,sizeof(vis));
	memset(d,127,sizeof(d));
	d[s]=/*vis[s]=*/false;
	while (q.size()){
		data z=q.top();q.pop();
		int u=z.u,len=z.len;
		if (len!=d[u]) continue;
		for(int i=h[u];i;i=e[i].next){
			register int v=e[i].to;
			if (d[v]>d[u]+e[i].w){
				d[v]=d[u]+e[i].w;
				q.push((data){v,d[v]});
			}
		}
	}
}
#define gc getchar()
#define g(c) isdigit(c)
inline int read(){
	char c=0;int x=0;bool f=0;
	while (!g(c)) f=c=='-',c=gc;
	while (g(c)) x=x*10+c-48,c=gc;
	return f?-x:x;
}
int n,m,a,b,i,s;
int main(){
	freopen("t1.in","r",stdin);
	n=read();m=read();s=read();
	for(i=1;i<=m;i++){
		a=read();b=read();
		add_edge(a,b,read());
	}
	dijkstra(s);
	for(i=1;i<=n;i++)
	printf("%d ",d[i]);
	return 0;
}

你可能感兴趣的:(原创)