• [GYM102900K]Traveling Merchant


    IV.[GYM102900K]Traveling Merchant

    首先,观察到路径一定是一个 ( ho) 形的东西,其中在 ( ho) 的交点之前,一直都是黑白点交替,到了交点处是两个同色点。

    于是我们就只保留异色边建一张图,则问题就转变为给你多对同色点,询问有无从 (1) 经过其中一个点到达另一个点的简单路径。

    考虑建出异色边图的圆方树。则我们只需以 (1) 为根遍历圆方树,将询问的两个圆点升到它们的父亲——两个方点,然后判断它们是否成祖孙关系即可。

    时间复杂度 (O(n))

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int T,n,m,c;
    char s[200100];
    namespace Tree{
    	vector<int>v[400100];
    	void ae(int x,int y){v[x].push_back(y),v[y].push_back(x);}
    	int dfn[400100],sz[400100],tot,fa[400100];
    	void dfs(int x,int P){
    		fa[x]=P,dfn[x]=++tot,sz[x]=1;
    		for(auto y:v[x])if(y!=P)dfs(y,x),sz[x]+=sz[y];
    	}
    }
    namespace Graph{
    	vector<int>v[200100];
    	int dfn[200100],low[200100],tot;
    	stack<int>s;
    	void Tarjan(int x){
    		dfn[x]=low[x]=++tot,s.push(x);
    		for(auto y:v[x]){
                if(!dfn[y]){
    				Tarjan(y),low[x]=min(low[x],low[y]);
    				if(low[y]>=dfn[x]){
    					c++;
    					while(s.top()!=y)Tree::ae(c,s.top()),s.pop();
                        Tree::ae(c,s.top()),s.pop();
                        Tree::ae(c,x);
                    }
                }else low[x]=min(low[x],dfn[y]);
            }
    	}
    }
    vector<pair<int,int> >q;
    int main(){
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d%d%s",&n,&m,s+1),c=n;
    		for(int i=1,x,y;i<=m;i++){
    			scanf("%d%d",&x,&y),x++,y++;
    			if(s[x]!=s[y])Graph::v[x].push_back(y),Graph::v[y].push_back(x);
    			else q.push_back(make_pair(x,y));
    		}
    		Graph::Tarjan(1),Tree::dfs(1,0);
    		bool ok=false;
    		for(auto i:q){
    			if(!Graph::dfn[i.first]||!Graph::dfn[i.second])continue;
    			int x=i.first,y=i.second;
    			if(Tree::fa[x])x=Tree::fa[x];
    			if(Tree::fa[y])y=Tree::fa[y];
    			if(Tree::dfn[x]>Tree::dfn[y])swap(x,y);
    			if(Tree::dfn[x]+Tree::sz[x]-1>=Tree::dfn[y]){ok=true;break;}
    		}
    		puts(ok?"yes":"no");
    		for(int i=1;i<=n;i++)Graph::dfn[i]=Graph::low[i]=0,Graph::v[i].clear();Graph::tot=0;
    		for(int i=1;i<=c;i++)Tree::dfn[i]=Tree::sz[i]=Tree::fa[i]=0,Tree::v[i].clear();c=0;
    		while(!Graph::s.empty())Graph::s.pop();
    		q.clear();
    	}
    	return 0;
    }
    

  • 相关阅读:
    hadoop-1.2.1-1.x86_64.rpm、jdk-7u45-linux-x64.tar.gz安装(64位)
    如何卸载rpm包
    html+css基础知识总结
    css常用公共样式
    jquery时间控件datepicker
    jquery事件重复绑定的快速解决方法
    原生javascript里jsonp的实现原理
    Bootstrap分页插件--Bootstrap Paginator
    数据库基础知识(1)--数据库php连接
    jQuery radio取值,checkbox取值,select取值
  • 原文地址:https://www.cnblogs.com/Troverld/p/14621520.html
Copyright © 2020-2023  润新知