求调 WA on #3
查看原帖
求调 WA on #3
1164775
Jadonyzx楼主2024/6/29 13:39
#include<bits/stdc++.h>
#define int long long
#define maxn 100010
#define maxm 200010
using namespace std;
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-'0',ch=getchar();
	return x*f;
}
inline void write(int x){
	if(x<0){
		putchar('-');
		write(-x);
		return;
	}
	if(x>=10)write(x/10);
	putchar(x%10+'0');
	return;
}
struct node{
	int id,dis;
	bool operator <(const node &ccf)const{return ccf.dis<dis;}
};
struct EDGE{
	int u,v,val,id;bool vis;
}edge[maxm],tree[maxm];
bool cmp(EDGE ccf,EDGE ioi){
	return ccf.val<ioi.val;
}
int n,m,cnt=1,ask,a[150][maxn],noip=1,go_up[maxn],ANS[maxn+10];
int fat[maxn],past[maxn],depth[maxn],fa[maxn][150],dis[maxn];
int tdis[maxn];
bool visit[maxn],vist[maxn],VIS[maxn];
int orz=1,fullcombo[maxn];
vector<EDGE>e[maxn],tre[maxn];
void addedge(int from,int to,int val)
{
	edge[++cnt].u=from;
	edge[cnt].v=to;
	edge[cnt].val=val;
	edge[cnt].id=cnt;
	edge[cnt].vis=false;
	e[from].push_back(edge[cnt]);
	return;
}
void treeaddedge(int from,int to,int val){
	tree[++noip].u=from;
	tree[noip].v=to;
	tree[noip].id=noip;
	tree[noip].vis=false;
	tree[noip].val=val;
	tre[from].push_back(tree[noip]);
	return;
}
int find(int rt){
	return (rt==fat[rt])?rt:fat[rt]=find(fat[rt]);
}
void kelusikaer(){
	sort(2+edge,1+edge+cnt,cmp);
	for(int i=2;i<=2+m*2;++i){
		int from=find(edge[i].u);
		int to=find(edge[i].v);
		if(from!=to){
			treeaddedge(edge[i].u,edge[i].v,edge[i].val);
			treeaddedge(edge[i].v,edge[i].u,edge[i].val);
			edge[i].vis=1;
			edge[i^1].vis=1;
			fat[from]=to;
		}
	}
	return;
}
void dfs(int rt,int ffa){
	depth[rt]=depth[ffa]+1;
	for(int i=0;i<=19;++i)
	fa[rt][i+1]=fa[fa[rt][i]][i];
	for(int i=0;i<tre[rt].size();++i){
		int to=tre[rt][i].v;
		int val=tre[rt][i].val;
		if(to==ffa)continue;
		fa[to][0]=rt;tdis[to]=tdis[rt]+val;
		dfs(to,rt);
	}
	return;
}
void dj(int rt){
	for(int i=1;i<=n;++i)dis[i]=1e12;
	dis[rt]=0;
	memset(vist,0,sizeof vist);
	priority_queue<node>Q;
	while(!Q.empty())Q.pop();
	Q.push(node{rt,0});
	while(!Q.empty()){
		int now=Q.top().id;
		int nowdis=dis[now];
		Q.pop();
		if(!vist[now]){
			vist[now]=1;
			for(int i=0;i<e[now].size();++i){
				int to=e[now][i].v;
				int val=e[now][i].val;
				if(nowdis+val<dis[to]){
					dis[to]=nowdis+val;
					if(!vist[to])Q.push(node{to,dis[to]});
				}
			}
		}
	}
	for(int i=1;i<=n;++i)a[fullcombo[rt]][i]=dis[i];
	return;
}
int lca(int x,int y){
	if(depth[x]<depth[y])swap(x,y);
	for(int i=20;i>=0;i--){
		if(depth[fa[x][i]]>=depth[y])x=fa[x][i];
	}
	if(x==y)return x;
	for(int i=20;i>=0;i--)
	if(fa[x][i]!=fa[y][i])
	x=fa[x][i],y=fa[y][i];
	return fa[x][0];
}
signed main()
{
	n=read();m=read();
	for(int i=1;i<=n;++i)fat[i]=i;
	for(int i=1;i<=m;++i){
		int from=read();
		int to=read();
		int value=read();
		addedge(from,to,value);
		addedge(to,from,value);
	}
	kelusikaer();
	depth[1]=1;tdis[1]=0;
	dfs(1,0);
	memset(VIS,0,sizeof VIS);
	memset(visit,0,sizeof visit);
	for(int i=1;i<=m+10;++i){
		if(!edge[i].vis){
			visit[edge[i].u]=1;
			visit[edge[i].v]=1;
		}
	}
	for(int i=1;i<=n;++i){
		//cout<<visit[i]<<'\n';
		if(visit[i]&&!VIS[i]){
			VIS[i]=1;
			fullcombo[i]=++orz;
		}
	}
	for(int i=1;i<=n;++i){if(visit[i])dj(i);}
	ask=read();
	for(int i=1;i<=ask;++i){
		int first=read(),second=read();
		int father=lca(first,second);
		int res=first;
		int ans=tdis[first]+tdis[second]-2*tdis[father];
		if(visit[first]){ans=min(ans,a[fullcombo[first]][second]);}
		//cout<<"suibian\n"<<a[fullcombo[first]][second]<<'\n';
		if(visit[second]){ans=min(ans,a[fullcombo[second]][first]);}
		//cout<<"suibian\n"<<a[fullcombo[second]][first]<<'\n';
		ANS[i]=ans;
	}
//	for(int i=2;i<=noip;i+=2){
//		cout<<tree[i].u<<' '<<tree[i].v<<' '<<tree[i].val<<'\n';
//	}
	for(int i=1;i<=ask;++i){write(ANS[i]);putchar('\n');}
	return 0;
}
/*
9 11
7 5 2
5 3 2
9 8 3
9 3 4
3 1 2
4 6 1
6 2 2
2 3 4
5 8 5
7 1 5
7 6 5
1
6 5

ans:
7
*/
2024/6/29 13:39
加载中...