zoukankan      html  css  js  c++  java
  • [题解]gdfzoj 902

    边双+LCA

    code

    #include<bits/stdc++.h>
    namespace my_std
    {
    	using namespace std;
    	#define rep(i,a,b) for (int i=(a);i<=(b);i++)
    	#define drep(i,a,b) for (int i=(a);i>=(b);i--)
    	#define go(u) for (int i=head[(u)];i;i=e[i].nxt)
    	#define pf printf
    	#define writeln(x) write(x),putchar('
    ')
    	#define writesp(x) write(x),putchar(' ')
    	#define mem(x,v) memset(x,v,sizeof(x))
    	typedef long long ll;
    	const int INF=0x7fffffff;
    	inline int read()
    	{
    		int sum=0,f=1;
    		char c=0;
    		while (!isdigit(c))
    		{
    			if (c=='-') f=-1;
    			c=getchar();
    		}
    		while (isdigit(c))
    		{
    			sum=(sum<<1)+(sum<<3)+(c^48);
    			c=getchar();
    		}
    		return sum*f;
    	}
    	void write(int k)
    	{
    		if (k<0) putchar('-'),k=-k;
    		if (k>=10) write(k/10);
    		putchar(k%10+'0');
    	}
    }
    using namespace my_std;
    const int N=100010;
    const int M=500010;
    int n,m,quiz;
    int cnt1,cnt2=1,head[N],HEAD[N];
    int idx,low[N],dfn[N];
    int col,color[N],sum[N],val[N];
    int sum_plus[N];
    int dep[N],f[N][21];
    bool bridge[M<<1];
    struct edge
    {
    	int to,nxt;
    }e[M<<1],E[M<<1];
    void add1(int u,int v)
    {
    	e[++cnt1].to=v;
    	e[cnt1].nxt=head[u];
    	head[u]=cnt1;
    }
    void add2(int u,int v)
    {
    	E[++cnt2].to=v;
    	E[cnt2].nxt=HEAD[u];
    	HEAD[u]=cnt2;
    }
    void tarjan(int u,int last)
    {
    	low[u]=dfn[u]=++idx;
    	for (int i=HEAD[u];i;i=E[i].nxt)
    	{
    		int v=E[i].to;
    		if (!dfn[v])
    		{
    			tarjan(v,i);
    			low[u]=min(low[u],low[v]);
    			if (low[v]>dfn[u])
    			{
    				bridge[i]=1;
    				bridge[i^1]=1;
    			}
    		}
    		else if (i!=(last^1)) low[u]=min(low[u],dfn[v]);
    	}
    }
    void get_color(int u,int r)
    {
    	color[u]=r;
    	sum[color[u]]+=val[u];
    	for (int i=HEAD[u];i;i=E[i].nxt)
    	{
    		int v=E[i].to;
    		if (!color[v]&&!bridge[i])
    		{
    			get_color(v,r);
    		}
    	}
    }
    void build_tree()
    {
    	rep(u,1,n)
    	{
    		for (int i=HEAD[u];i;i=E[i].nxt)
    		{
    			int v=E[i].to;
    			if (bridge[i])
    			{
    				add1(color[u],color[v]);
    			}
    		}
    	}
    }
    void dfs(int u,int fa)
    {
    	dep[u]=dep[fa]+1;
    	f[u][0]=fa;
    	for (int i=1;(1<<i)<=dep[u];i++)
    	{
    		f[u][i]=f[f[u][i-1]][i-1];
    	}
    	go(u)
    	{
    		int v=e[i].to;
    		if (v==fa) continue;
    		dfs(v,u);
    	}
    }
    int lca(int x,int y)
    {
    	if (dep[x]<dep[y]) swap(x,y);
    	drep(i,20,0)
    	{
    		if (dep[f[x][i]]>=dep[y]) x=f[x][i];
    		if (x==y) return x;
    	}
    	drep(i,20,0)
    	{
    		if (f[x][i]!=f[y][i])
    		{
    			x=f[x][i];
    			y=f[y][i];
    		}
    	}
    	return f[x][0];
    }
    void getsum(int u,int fa)
    {
    	sum_plus[u]=sum_plus[fa]+sum[u];
    	go(u)
    	{
    		int v=e[i].to;
    		if (v==fa) continue;
    		getsum(v,u);
    	}
    }
    int solve(int u,int v)
    {
    	if (color[u]==color[v]) return sum[color[u]];
    	int LCA=lca(color[u],color[v]);
    	int ans=sum_plus[color[u]]+sum_plus[color[v]]-sum_plus[LCA]-sum_plus[f[LCA][0]];
    	return ans;
    }
    int main()
    {
    	n=read(),m=read();quiz=read();
    	rep(i,1,n) val[i]=read();
    	int u,v;
    	rep(i,1,m)
    	{
    		u=read(),v=read();
    		add2(u,v),add2(v,u);
    	}
    	tarjan(1,-INF);
    	rep(i,1,n) if (!color[i]) get_color(i,++col);
    	build_tree();
    	dfs(color[1],0);
    	getsum(color[1],0);
    	rep(i,1,quiz)
    	{
    		u=read(),v=read();
    		writeln(solve(u,v));
    	}
    }
    
    

    进阶版:BZOJ 2959

  • 相关阅读:
    [HEOI2016/TJOI2016]树
    [BJOI2018]求和
    洛谷P5002 专心OI
    [GDOI2014]采集资源
    小凯的数字
    APP微信支付
    java对接支付宝支付
    layui 视频上传本地(项目)
    mybatis Generator生成代码及使用方式
    Java IO流学习总结
  • 原文地址:https://www.cnblogs.com/ZHANG-SHENG-HAO/p/12420531.html
Copyright © 2011-2022 走看看