求卡常
查看原帖
求卡常
204705
KiDDOwithTopTree楼主2022/7/17 11:35

真的卡不动了QAQ,帮忙卡一下常或看看哪里写出了吧。(倍增优化建图)

#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int N=5e4+10,M=1e7+10;
const int INF=0x3f3f3f3f;
inline int read(){
	int x(0),f(1);char ch(getchar());
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
int fa[N];
inline int get_rt(int x){
	return x==fa[x]?x:fa[x]=get_rt(fa[x]);
}
struct edge_node{
	int from,to;
	int val;
	int nxt;
};
struct edge{
	edge_node e[M];
	int head[M],tot;
	edge(){
		memset(head,-1,sizeof head);
	}
	inline void add(int from,int to,int val){
		e[tot].from=from;
		e[tot].to=to;
		e[tot].val=val;
		e[tot].nxt=head[from];
		head[from]=tot++;
	}
};
edge e1,e2;
int f[N][30],dep[N];
int p[N][30],q[N][30],cnt;
void dfs(int u,int fa){
	f[u][0]=fa,dep[u]=dep[fa]+1;
	p[u][0]=++cnt,q[u][0]=++cnt;
	e2.add(u,p[u][0],0),e2.add(fa,p[u][0],0);
	e2.add(q[u][0],u,0),e2.add(q[u][0],fa,0);
	for(int i(1);i<=20;++i){
		f[u][i]=f[f[u][i-1]][i-1];
		p[u][i]=++cnt,q[u][i]=++cnt;
		e2.add(p[u][i-1],p[u][i],0);
		e2.add(p[f[u][i-1]][i-1],p[u][i],0);
		e2.add(q[u][i],q[u][i-1],0);
		e2.add(q[u][i],q[f[u][i-1]][i-1],0);
	}
	for(int i(e1.head[u]);~i;i=e1.e[i].nxt){
		int v(e1.e[i].to),w(e1.e[i].val);
		if(v==fa) continue;
		e2.add(u,v,w),e2.add(v,u,w);
		dfs(v,u);
	}
}
void add1(int x,int y,int val){
	if(dep[x]<dep[y]) swap(x,y);
	for(int i=(20);i>=0;--i){
		if(dep[f[x][i]]>=dep[y]){
			e2.add(p[x][i],cnt,val);
			x=f[x][i];
		}
	}
	if(x==y) return e2.add(x,cnt,val);
	for(int i=(20);i>=0;--i){
		if(f[x][i]!=f[y][i]){
			e2.add(p[x][i],cnt,val);
			e2.add(p[y][i],cnt,val);
			x=f[x][i],y=f[y][i];
		}
	}
	e2.add(p[x][0],cnt,val);
	e2.add(p[y][0],cnt,val);
}
void add2(int x,int y){
	if(dep[x]<dep[y]) swap(x,y);
	for(int i=(20);i>=0;--i){
		if(dep[f[x][i]]>=dep[y]){
			e2.add(cnt,q[x][i],0);
			x=f[x][i];
		}
	}
	if(x==y) return e2.add(cnt,x,0);
	for(int i=(20);i>=0;--i){
		if(f[x][i]!=f[y][i]){
			e2.add(cnt,q[x][i],0);
			e2.add(cnt,q[y][i],0);
			x=f[x][i],y=f[y][i];
		}
	}
	e2.add(cnt,q[x][0],0);
	e2.add(cnt,q[y][0],0);
}
struct node{
	int dis,pos;
	inline bool operator<(node x)const{
		return dis>x.dis;
	}
};
priority_queue<node> h;
int dis[200*N];
bool vis[200*N];
void dijkstra(int s){
	memset(dis,0x3f,sizeof dis);
	node tmp;
	tmp.dis=dis[tmp.pos=s]=0;
	h.push(tmp);
	while(!h.empty()){
		int u(h.top().pos);
		h.pop();
		if(vis[u]) continue;
		vis[u]=true;
		for(int i(e2.head[u]);~i;i=e2.e[i].nxt){
			int v(e2.e[i].to),w(e2.e[i].val);
			if(dis[v]>dis[u]+w){
				tmp.dis=dis[tmp.pos=v]=dis[u]+w;
				h.push(tmp);
			}
		}
	}
}
struct quest{
	int opt,u1,v1,u2,v2,w;
};
quest que[20*N];
signed main(){
	int n(read()),m(read()),s(read()),num(0);
	for(int i(1);i<=n;++i) fa[i]=i;
	int fx1,fx2,fy1,fy2,fx,fy;
	for(int i(1);i<=m;++i){
		que[++num].opt=read();
		if(que[num].opt==1){
			que[num].u1=read();
			que[num].v1=read();
			que[num].u2=read();
			que[num].v2=read();
			que[num].w=read();
			fx1=get_rt(que[num].u1);
			fy1=get_rt(que[num].v1);
			fx2=get_rt(que[num].u2);
			fy2=get_rt(que[num].v2);
			if(fx1!=fy1||fx2!=fy2) --num;
		}
		else{
			que[num].u1=read();
			que[num].v1=read();
			que[num].w=read();
			fx=get_rt(que[num].u1);
			fy=get_rt(que[num].v1);
			if(fx!=fy){
				fa[fx]=fy;
				e1.add(que[num].u1,que[num].v1,que[num].w);
				e1.add(que[num].v1,que[num].u1,que[num].w);
			}
			--num;
		}
	}
	cnt=n;
	for(int i(1);i<=n;++i)
		if(fa[i]==i) dfs(i,0);
	for(int i(1);i<=num;++i){
		++cnt;
		add1(que[i].u1,que[i].v1,que[i].w);
		add2(que[i].u2,que[i].v2);
	}
	dijkstra(s);
	for(int i(1);i<=n;++i)
		if(dis[i]>=INF) printf("-1 ");
		else printf("%d ",dis[i]);
}
2022/7/17 11:35
加载中...