wtcl 样例不过
查看原帖
wtcl 样例不过
54372
A_Đark_Horcrux楼主2020/11/25 15:53

QAQ

#include<cstdio>
#include<queue>
#define il inline
using namespace std;
typedef long long ll;
const int N=1e5+10;
const ll inf=192608171919810;
il ll read()
{
	ll s=0; char c=getchar();
	while(c<'0'||c>'9') c=getchar();
	while(c>='0'&&c<='9') s=s*10+c-'0',c=getchar();
	return s;
}
struct edge{int next,to,dis;}a[N*2];//链式前向星
struct node
{
	ll s; int n;
	bool operator < (const node &x) const
	{
		return x.s<s;
	}
}now;//dij用的结构体
priority_queue<node,vector<node>,less<node> >q;//dij用的堆 
int n,m,start,t,cnt,r1,r2;
int ls[N],rs[N],h[N]; ll dis[N]; bool b[N];
il void add(int x,int y,int z)
{
	a[t].next=h[x],a[t].to=y,a[t].dis=z,h[x]=t;
	a[t].next=h[y],a[t].to=x,a[t].dis=z,h[y]=t;
}//加边
void build_out(int l,int r,int &p)
{
	if(l==r) {p=l; return ;}
	p=++cnt;
	int mid=(l+r)>>1;
	build_out(l,mid,ls[p]); build_out(mid+1,r,rs[p]);
	add(p,ls[p],0); add(p,rs[p],0);
	return ;
}//出树
void build_in(int l,int r,int &p)
{
	if(l==r) {p=l; return ;}
	p=++cnt;
	int mid=(l+r)>>1;
	build_in(l,mid,ls[p]); build_in(mid+1,r,rs[p]);
	add(ls[p],p,0); add(rs[p],p,0);
	return ;
}//入树
void update1(int x,int y,int l,int r,int p,int f,int w)//x,y:连边区间左右端点 l,r:线段树上区间左右端点 p:连边的点 f:树根 w:边权
{
    if(x<=l&&r<=y) {add(f,p,w); return ;}
    int mid=(l+r)>>1;
    if(x<=mid) update1(x,y,l,mid,ls[p],f,w);
    if(y>mid) update1(x,y,mid+1,r,rs[p],f,w);
    return ;
}//操作2
void update2(int x,int y,int l,int r,int p,int f,int w)
{
    if(x<=l&&r<=y) {add(p,f,w); return ;}
    int mid=(l+r)>>1;
    if(x<=mid) update2(x,y,l,mid,ls[p],f,w);
    if(y>mid) update2(x,y,mid+1,r,rs[p],f,w);
    return ;
}//操作3
void dij()
{
	for(int i=1;i<=n;i++) dis[i]=inf;
    dis[start]=0; q.push((node){0,start});
    while(!q.empty())
    {
    	now=q.top(); q.pop();
		if(!b[now.n])
		{
			b[now.n]=1;
			for(int i=h[now.n];i;i=a[i].next)
			{
				int y=a[i].to;
				if(dis[y]>dis[now.n]+a[i].dis)
					dis[y]=dis[now.n]+a[i].dis,q.push((node){y,dis[y]});
			}	
		}
	}
	return ;
}//dij
int main()
{
	n=read(),m=read(),start=read(); cnt=n;
	build_out(1,n,r1); build_in(1,n,r2);
	while(m--)
	{
		int x,l,r,z,f;
		f=read();
		if(f==1) x=read(),l=read(),z=read(),add(x,l,z);
		else if(f==2) x=read(),l=read(),r=read(),z=read(),update1(l,r,1,n,x,r1,z);
		else x=read(),l=read(),r=read(),z=read(),update2(l,r,1,n,x,r2,z);
	}
	dij();
	for(int i=1;i<=n;i++) printf("%lld ",dis[i]==1145141919810?-1:dis[i]);
	printf("%lld",dis[n]);
	return 0;
}
2020/11/25 15:53
加载中...