• 单源最短路径


    封装了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;
    }
    
  • 相关阅读:
    java判断字符串为字母
    ListView获取当前最顶部的item
    Android自适应屏幕大小和layout布局
    生成器,推导式
    迭代器,闭包,递归
    函数的进阶
    初识函数
    编码的进阶,文件操作,深浅copy
    代码块,数据类型的相互转换,集合
    字典及相关操作
  • 原文地址:https://www.cnblogs.com/thedreammaker/p/16180356.html
Copyright © 2020-2023  润新知