ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF1051F The Shortest Statement

2021-02-12 22:02:18  阅读:243  来源: 互联网

标签:tmp cur int top CF1051F Statement lca son Shortest


题面传送门
zyq扒原题不要脸!
题目要我们求图上任意两点间最短路。
这个显然很难解决。
于是我们可以观察一下数据范围。
然后就可以发现一个奇怪的事情,最多只是生成树上加\(21\)条边。
考虑先随便搞出一棵生成树。然后对于这\(21\)条边强制走,剩下的生成树上lca即可。
然而,这道题zyq丧心病狂地卡了空间,所以只能用树剖lca而不能用倍增lca。
code:

#include<cstdio>
#include<queue>
#include<cstring>
#define beg(x) int cur=s.h[x]
#define end cur
#define go cur=tmp.z
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
int n,m,k,x,y,z,f[100039],cnt,un,wn,tot,id[100039],flag[139],head,now,pus,fl[100039],lcas;
int d[100039],siz[100039],son[100039],top[100039],fa[100039];
long long de[100039],dis[49][100039],ans;
struct yyy{int to,w,z;}tmp;
struct ljb{
	int head,h[100039];yyy f[200039];
	inline void add(int x,int y,int z){f[++head]=(yyy){y,z,h[x]},h[x]=head;}
}s,g;
inline int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
inline void dfs1(int x,int last){
	fa[x]=last;d[x]=d[last]+1,siz[x]=1;yyy tmp;
	for(beg(x);end;go){
		tmp=s.f[cur];
		if(tmp.to^last)de[tmp.to]=de[x]+tmp.w,dfs1(tmp.to,x),siz[x]+=siz[tmp.to],son[x]=siz[son[x]]>siz[tmp.to]?son[x]:tmp.to;
	}
}
inline void dfs2(int x,int last){
	top[x]=last;if(!son[x]) return;dfs2(son[x],last);yyy tmp;
	for(beg(x);end;go){
		tmp=s.f[cur];
		if((tmp.to^fa[x])&&(tmp.to^son[x])) dfs2(tmp.to,tmp.to);
	}
}
inline int lca(int x,int y){
	while(top[x]!=top[y]) d[top[x]]>d[top[y]]?(x=fa[top[x]]):(y=fa[top[y]]);
	return d[x]>d[y]?y:x;
}
struct ques{
	int to;long long w;
	bool operator <(const ques &x)const{return w>x.w;}
}tmps;
priority_queue<ques> q;
int main(){
	freopen("1.in","r",stdin);
	register int i,j;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++) f[i]=i;
	for(i=1;i<=m;i++){
		scanf("%d%d%d",&x,&y,&z);
		un=find(x);wn=find(y);
		if(un!=wn&&cnt<n-1){
			f[un]=wn;s.add(x,y,z);s.add(y,x,z);cnt++;
		}
		else{
			id[x]=id[x]?id[x]:(id[x]=++tot,flag[tot]=x);
			id[y]=id[y]?id[y]:(id[y]=++tot,flag[tot]=y);
		}
		g.add(x,y,z);g.add(y,x,z);
	}
	dfs1(1,0);dfs2(1,1);s=g;
	memset(dis,0x3f,sizeof(dis));
	for(i=1;i<=tot;i++){
		pus=flag[i];dis[i][pus]=0;q.push((ques){pus,0});
		while(!q.empty()){
			tmps=q.top();q.pop();fl[tmps.to]=0;
			for(beg(tmps.to);end;go){
				tmp=s.f[cur];
				if(dis[i][tmp.to]>dis[i][tmps.to]+tmp.w){
					dis[i][tmp.to]=dis[i][tmps.to]+tmp.w;
					if(!fl[tmp.to]) q.push((ques){tmp.to,dis[i][tmp.to]}),fl[tmp.to]=1;
				}
			}
		}
	}
	scanf("%d",&k);while(k--){
		scanf("%d%d",&x,&y);ans=1e18;
		lcas=lca(x,y);ans=min(ans,de[x]+de[y]-2*de[lcas]);
		for(i=1;i<=tot;i++)ans=min(ans,dis[i][y]+dis[i][x]);
		printf("%lld\n",ans);
	}
}

标签:tmp,cur,int,top,CF1051F,Statement,lca,son,Shortest
来源: https://www.cnblogs.com/275307894a/p/14399399.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有