单源最短路径

封装了dijkstra和johnson的板子

dijkstra(johnson明天更):

#include <bits/stdc++.h>
#define min(x, y) ((x) < (y) ? (x) : (y))
#define max(x, y) ((x) > (y) ? (x) : (y))
#define Fanv(x) for(int i=edge::sum[x-1]+1,now_v=edge::e[i].y;i<=edge::sum[x];i++,now_v=edge::e[i].y)  //For_all_neighbor_vertex 枚举x的所有邻居,now_v=当前枚举的邻居 
const int N=100000,M=200000,type=0;//点数,边数最大值(开空间用),有向图type=0,无向图为1 
using namespace std;
namespace Fast_IO {
	int read() {
		int x(0);
		char ch(getchar());
		while(ch>'9'||ch<'0')ch=getchar();
		while(ch<='9'&&ch>='0') {
			x=x*10+ch-'0';
			ch=getchar();
		}
		return x;
	}
}
namespace edge {
	int n,m,sum[N+1],cnt(0);
	struct element {
		int x,y,len;//边的起点,终点,边权
		bool operator < (const element a)const {
			if(x!=a.x)return x<a.x;
			else return y<a.y;
		}
	} e[(1+type)*M+1];
	inline void add_edge(int st,int en,int val) {
		e[++cnt].x=st;
		e[cnt].y=en;
		e[cnt].len=val;
	}
	void work() {
		e[0].x=e[0].y=0;
		sum[0]=0;
		std::sort(e+1,e+cnt+1);
		for(int i=1; i<=cnt; i++) {
			if(e[i].x!=e[i+1].x) {
				sum[e[i].x]=i;
			}
		}
		for(int i=1; i<=n; i++)sum[i]=max(sum[i],sum[i-1]);
	}
	void reset() {
		cnt=0;
	}
}
namespace Dijkstra {
	int ls(int x) {
		return x<<1;
	}
	int rs(int x) {
		return (x<<1)+1;
	}
	int INF(1e9+1),start,ans[4*N+5],ans_pos[4*N+5],dis[N+1],b[N+1],n,m;
	void push_up(int id) {
		if(ans[ls(id)]<=ans[rs(id)]) {
			ans[id]=ans[ls(id)];
			ans_pos[id]=ans_pos[ls(id)];
		} else {
			ans[id]=ans[rs(id)];
			ans_pos[id]=ans_pos[rs(id)];
		}
	}
	void build(int l,int r,int id) {
		if(l==r) {
			if(l!=start)ans[id]=INF;
			else ans[id]=0;
			ans_pos[id]=l;
			return;
		}
		int mid((l+r)>>1);
		build(l,mid,ls(id));
		build(mid+1,r,rs(id));
		push_up(id);
		return;
	}
	void opc(int pos,int l,int r,int id,long long int zhi,int type) {
		if(l==r) {
			if(type)ans[id]=min(ans[id],zhi);
			else ans[id]=zhi;
			return;
		}
		int mid((l+r)>>1);
		if(pos<=mid)opc(pos,l,mid,ls(id),zhi,type);
		else opc(pos,mid+1,r,rs(id),zhi,type);
		push_up(id);
		return;
	}
	void Solve(int n) {
		build(1,n,1);
		int T=n;
//		dis[start]=0;
		while(T--) {
			int now=ans_pos[1],now_len=ans[1];
			dis[now]=now_len;
			b[now]=1;
			opc(now,1,n,1,INF,0);
			Fanv(now) {
				if(!b[now_v]&&now_v!=now) {
					opc(now_v,1,n,1,now_len+edge::e[i].len,1);
				}
			}
		}
	}
	void reset() {
		memset(b,0,sizeof(b)); 
	}
}
int main() {
	edge::n=Fast_IO::read();
	edge::m=Fast_IO::read();
	Dijkstra::start=Fast_IO::read();
	for(int i=1; i<=edge::m; i++) {
		int x,y,len;
		x=Fast_IO::read();
		y=Fast_IO::read();
		len=Fast_IO::read();
		edge::add_edge(x,y,len);
//		edge::add_edge(y,x,len);
	}
	edge::work();
	Dijkstra::Solve(edge::n);
	for(int i=1; i<=edge::n; i++)
		printf("%d ",Dijkstra::dis[i]);
	return 0;
}
posted @ 2022-04-22 19:59  永无岛  阅读(42)  评论(0编辑  收藏  举报