图论---LCA(Tarjan 离线做法)

#include
using namespace std;
typedef pair pii;
const int N=20010,M=2*N;//是无向边,边需要见两边

int n,m;
vector g[N];
int p[N];
//求一下每个点到根节点之间的距离
int dist[N];
int res[N];//存结果
// first存查询的另外一个点是谁
// second 存查询编号
vector query[N];
int st[N];

void dfs(int u,int fa){
	//遍历u 的所有邻点
	for(auto e:g[u]){
		int v=e.first;
		if(v==fa) continue;
		dist[v]=dist[u]+e.second;
		dfs(v,u);
	}
}

int find(int x){
	while(p[x]!=x){
		p[x]=p[p[x]];
		x=p[x];
	}
	return x;
}

void tarjan(int u){
	st[u]=1;
	for(auto e:g[u]){
		int v=e.first;
		if(!st[v]){
			tarjan(v);
			p[v]=u;
		}
	}
	for(auto x:query[u]){
		int y=x.first,id = x.second;
		if(st[y]==2){
			int anc=find(y);
			res[id]=dist[u]+dist[y]-2*dist[anc];
		}
	}
	st[u]=2;
}

int main(){
	cin>>n>>m;
	for(int i=0;i>a>>b>>c;
		g[a].push_back({b,c}),g[b].push_back({a,c});
	}
	for(int i=0;i>a>>b;
		if(a!=b){
			query[a].push_back({b,i});
			query[b].push_back({a,i});
		}
		//a==b 是0 刚好不用处理
	}
	for(int i=1;i<=n;++i) p[i]=i;
	dfs(1,-1);
	tarjan(1);
	for(int i=0;i

 

 

你可能感兴趣的:(图论,算法,数据结构)