求助,圆方树全WA
查看原帖
求助,圆方树全WA
252549
Iwara楼主2024/7/21 22:47

RT

感觉写的没啥问题

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN=1e5+5;
ll n,m,q;
ll x,y,z;
struct edge{
	ll u,v,w,nxt;
}e[MAXN],tree[MAXN];
ll head[MAXN],edge_num;
void add_edge(ll From,ll To,ll Len){
	e[++edge_num]=(edge){From,To,Len,head[From]};
	head[From]=edge_num;
	return;
}
ll head_tree[MAXN],tree_num;
void add_tree(ll From,ll To,ll Len){
	tree[++tree_num]=(edge){From,To,Len,head_tree[From]};
	head_tree[From]=tree_num;
	return;
}
ll dfn[MAXN],low[MAXN],cnt,st[MAXN],top;
ll tot;
void tarjan(ll now,ll father){
	dfn[now]=low[now]=++cnt;
	st[++top]=now;
	for(int i=head[now];i;i=e[i].nxt){
		if(!dfn[e[i].v]){
			tarjan(e[i].v,now);
			low[now]=min(low[now],low[e[i].v]);
			if(low[e[i].v]>=dfn[now]){
				tot++;
				while(st[top+1]!=e[i].v){
					add_tree(tot,st[top],0);
					add_tree(st[top],tot,0);
					top--;
				}
				add_tree(tot,st[top],0);
				add_tree(st[top],tot,0);
			}
		}
		else if(e[i].v!=father)low[now]=min(low[now],dfn[e[i].v]);
	}
	return;
}
ll deep[MAXN],fa[MAXN][35];
void pre(ll now,ll father){
	for(int i=1;i<=30;i++)fa[now][i]=fa[fa[now][i-1]][i-1];
	for(int i=head_tree[now];i;i=tree[i].nxt){
		if(tree[i].v==father)continue;
		deep[tree[i].v]=deep[now]+1;
		fa[tree[i].v][0]=now;
		pre(tree[i].v,now);
	}
	return;
}
ll dis_on_ring[MAXN],sum[MAXN];
bool on_ring[MAXN];
bool vis[MAXN];
void pre_square(ll now){
	ll qwq=0;
	for(int i=head_tree[now];i;i=tree[i].nxt)on_ring[tree[i].v]=1,qwq++;
	ll st=fa[now][0];
	if(qwq==2){
		ll _end=0,tmp=0;
		for(int i=head_tree[now];i;i=tree[i].nxt)if(tree[i].v!=st)_end=tree[i].v;
		for(int i=head[st];i;i=e[i].nxt){
			if(e[i].v==_end){
				tmp++;
				sum[now]+=e[i].w;
				dis_on_ring[_end]=e[i].w;
			}
		}
		if(tmp==1)sum[now]<<=1;
		for(int i=head_tree[now];i;i=tree[i].nxt)if(tree[i].v==_end)tree[i].w=min(dis_on_ring[_end],sum[now]-dis_on_ring[_end]);
		for(int i=head_tree[now];i;i=tree[i].nxt)on_ring[tree[i].v]=0;
		return;
	}
	ll now_p=st,nxt=0,now_len=0;
	while(1){
		vis[now_p]=1;
		for(int i=head[now_p];i;i=e[i].nxt){
			if(vis[e[i].v]||(on_ring[e[i].v]==0))continue;
			nxt=e[i].v;
			now_len+=e[i].w;
			break;
		}
		if(nxt==0||nxt==now_p)break;
		dis_on_ring[nxt]=now_len;
		sum[now]=now_len;
		now_p=nxt;
	}
	for(int i=head[now_p];i;i=e[i].nxt)if(e[i].v==st){
		sum[now]+=e[i].w;
		break;
	}
	for(int i=head_tree[now];i;i=tree[i].nxt){
		if(tree[i].v==st)continue;
		tree[i].w=min(dis_on_ring[tree[i].v],sum[now]-dis_on_ring[tree[i].v]);
	}
	for(int i=head_tree[now];i;i=tree[i].nxt)on_ring[tree[i].v]=vis[tree[i].v]=0;
	return;
}
ll dis[MAXN];
void get_dis(ll now,ll father){
//	cout<<"now "<<now<<endl;
	for(int i=head_tree[now];i;i=tree[i].nxt){
		if(tree[i].v==father)continue;
		dis[tree[i].v]=dis[now]+tree[i].w;
		get_dis(tree[i].v,now);
	}
	return;
}
ll solve(ll X,ll Y){
	if(deep[X]<deep[Y])swap(X,Y);
	for(int i=30;i>=0;i--)if(deep[fa[X][i]]>=deep[Y])X=fa[X][i];
	for(int i=30;i>=0;i--)if(fa[X][i]!=fa[Y][i])X=fa[X][i],Y=fa[Y][i];
	if(fa[X][0]<=n)return dis[x]+dis[y]-2*dis[fa[X][0]];
	else{
		if(dis_on_ring[X]<dis_on_ring[Y])swap(X,Y);
		ll LEN=min(dis_on_ring[X]-dis_on_ring[Y],sum[fa[X][0]]-dis_on_ring[X]+dis_on_ring[Y]);
		return dis[x]+dis[Y]-dis[X]-dis[Y]+LEN;
	}
}
int main(){
	cin>>n>>m>>q;
	for(int i=1;i<=m;i++){
		cin>>x>>y>>z;
		if(x==y)continue;
		add_edge(x,y,z);
		add_edge(y,x,z); 
	}
	tot=n;
	tarjan(1,0);
//	cout<<endl;
//	for(int i=1;i<=tree_num;i++)cout<<tree[i].u<<" "<<tree[i].v<<endl;
	pre(1,0);
	for(int i=n+1;i<=tot;i++)pre_square(i);
//	cout<<endl;
//	for(int i=1;i<=tree_num;i++)cout<<tree[i].u<<" "<<tree[i].v<<" "<<tree[i].w<<endl;
	get_dis(1,0);
//	cout<<"?\n";
	for(int i=1;i<=q;i++){
		cin>>x>>y;
		cout<<solve(x,y)<<'\n';
	}
	return 0;
} 
2024/7/21 22:47
加载中...