zoukankan      html  css  js  c++  java
  • CF639F Bear and Chemistry

    题目传送门

    分析:
    题目描述的条件实际上是在要求所有点在同一个边双连通分量中
    先在原图跑tarjan,缩点建树,
    询问的点和加入的边的点处理之后变成边双上的点
    然后建虚树,在虚树上跑tarjan就好了
    不难,写起来真恶心

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<map>
    #include<vector>
    
    #define maxn 600005
    #define MOD 1000000007
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    inline long long getint()
    {
        long long num=0,flag=1;char c;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
        while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
        return num*flag;
    }
    
    int n,m,q,R;
    int fir[maxn],nxt[maxn],to[maxn],cnt;
    int sz[maxn],tp[maxn],fa[maxn],son[maxn],dpt[maxn],pos[maxn],cur;
    map<pair<int,int>,int>M;
    int p[maxn],V[maxn];
    int P_stk[maxn],P_Tp;
    
    inline int rotate(int x){x=(x+R)%n;return x?x:x+n;}
    inline bool cmp(int x,int y)
    {return pos[x]<pos[y];}
    inline void newnode(int u,int v)
    {to[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;}
    inline void dfs1(int u)
    {
    	sz[u]=1;pos[u]=++cur;
    	for(int i=fir[u];i;i=nxt[i])if(to[i]!=fa[u])
    	{
    		fa[to[i]]=u,dpt[to[i]]=dpt[u]+1;
    		dfs1(to[i]),sz[u]+=sz[to[i]];
    		if(sz[to[i]]>sz[son[u]])son[u]=to[i];
    	}
    }
    inline void dfs2(int u,int ac)
    {
    	tp[u]=ac;if(son[u])dfs2(son[u],ac);
    	for(int i=fir[u];i;i=nxt[i])if(to[i]!=fa[u]&&to[i]!=son[u])dfs2(to[i],to[i]);
    }
    inline int LCA(int u,int v)
    {
    	for(;tp[u]!=tp[v]&&u&&v;u=fa[tp[u]])if(dpt[tp[u]]<dpt[tp[v]])swap(u,v);
    	if(!u||!v)return 0;
    	return dpt[u]<dpt[v]?u:v;
    }
    
    struct node{
    	vector<int>G[maxn],Id[maxn];
    	int dfn[maxn],low[maxn],tim,vis[maxn],sccno[maxn],scccnt;
    	int stk[maxn],Tp;
    	
    	inline void tarjan(int u)
    	{
    		dfn[u]=low[u]=++tim;stk[++Tp]=u;
    		for(int i=0,v;i<G[u].size();i++)if(!vis[Id[u][i]])
    		{
    			vis[Id[u][i]]=1;
    			if(!dfn[v=G[u][i]])tarjan(v),low[u]=min(low[u],low[v]);
    			else if(!sccno[v])low[u]=min(low[u],dfn[v]);
    		}
    		if(dfn[u]==low[u])
    		{
    			scccnt++;
    			while(1){sccno[stk[Tp]]=scccnt;if(stk[Tp--]==u)break;}
    		}
    	}
    	inline void init()
    	{
    		for(int i=1;i<=m;i++)
    		{
    			int u=getint(),v=getint();
    			G[u].push_back(v),G[v].push_back(u);
    			Id[u].push_back(i),Id[v].push_back(i);
    		}
    		for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
    		for(int u=1;u<=n;u++)for(int i=0;i<G[u].size();i++)if(sccno[G[u][i]]!=sccno[u])
    		{
    			int x=min(sccno[u],sccno[G[u][i]]),y=max(sccno[u],sccno[G[u][i]]);
    			if(!M[make_pair(x,y)])newnode(x,y),newnode(y,x),M[make_pair(x,y)]=1;
    		}
    	}
    }G,H;
    
    int main()
    {
    	n=getint(),m=getint(),q=getint();
    	G.init();
    	for(int i=1;i<=G.scccnt;i++)if(!sz[i])dfs1(i),dfs2(i,i);
    	for(int t=1;t<=q;t++)
    	{
    		int N=getint(),M=getint(),K=0,tmp=0;P_Tp=0;
    		for(int i=1;i<=N;i++)
    		{
    			int x=G.sccno[rotate(getint())];
    			p[++K]=x,V[x]=1;
    		}
    		for(int i=1;i<=M;i++)
    		{
    			int x=G.sccno[rotate(getint())],y=G.sccno[rotate(getint())];
    			if(x==y)continue;
    			p[++K]=x,p[++K]=y,tmp++;
    			H.G[x].push_back(y),H.G[y].push_back(x);
    			H.Id[x].push_back(tmp),H.Id[y].push_back(tmp);
    		}
    		sort(p+1,p+K+1,cmp),K=unique(p+1,p+K+1)-p-1;
    		for(int i=K-1;i;i--)
    		{
    			int x=LCA(p[i],p[i+1]);
    			if(x)p[++K]=x;
    		}
    		sort(p+1,p+K+1,cmp),K=unique(p+1,p+K+1)-p-1;
    		for(int i=1;i<=K;i++)
    		{
    			while(P_Tp&&pos[P_stk[P_Tp]]+sz[P_stk[P_Tp]]<=pos[p[i]])P_Tp--;
    			if(P_Tp)
    			{
    				int x=P_stk[P_Tp],y=p[i];tmp++;
    				H.G[x].push_back(y),H.G[y].push_back(x);
    				H.Id[x].push_back(tmp),H.Id[y].push_back(tmp);
    			}
    			P_stk[++P_Tp]=p[i];
    		}
    		for(int i=1;i<=K;i++)if(!H.dfn[p[i]])H.tarjan(p[i]);
    		int pp=0;bool flg=1;
    		for(int i=1;i<=K;i++)if(V[p[i]])
    		{
    			if(!pp)pp=H.sccno[p[i]];
    			else if(pp!=H.sccno[p[i]]){flg=0;break;}
    		}
    		for(int i=1;i<=K;i++)
    		{
    			H.G[p[i]].clear(),H.Id[p[i]].clear();
    			H.dfn[p[i]]=H.low[p[i]]=H.sccno[p[i]]=V[p[i]]=0;
    		}
    		for(int i=1;i<=tmp;i++)H.vis[i]=0;
    		H.scccnt=H.tim=H.Tp=0;
    		R=(R+t*flg)%n;
    		puts(flg?"YES":"NO");
    	}
    }
    

  • 相关阅读:
    聊聊Spark的分区、并行度 —— 前奏篇
    深入探讨HBASE
    分布式流平台Kafka
    GeoServer中使用SLD样式
    OpenLayer修改WFS中的要素
    leaflet加载GeoServer的WFS服务
    OL实现属性查询的功能
    OL3实现空间查询的代码示例
    WFS—GetFeature方法
    OpenLayer+Geoserver+postgis实现路径分析
  • 原文地址:https://www.cnblogs.com/Darknesses/p/13052389.html
Copyright © 2011-2022 走看看