QOJ.ac

QOJ

ID提交记录ID题目HackerOwner结果提交时间测评时间
#771#508272#8029. Traveling MerchantShunpowerShunpowerSuccess!2024-08-07 20:24:542024-08-07 20:24:54

详细

Extra Test:

Wrong Answer
time: 4ms
memory: 18060kb

input:

1
9 11
LHLHLHLHL
0 1
1 2
2 3
3 4
4 5
5 6
2 7
7 8
0 3
3 6
6 8

output:

yes

result:

wrong answer 1st lines differ - expected: 'no', found: 'yes'

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#508272#8029. Traveling MerchantShunpowerWA 121ms59772kbC++145.0kb2024-08-07 12:03:562024-08-07 20:26:28

answer

//Author:KIT / Shunpower
//May the force be with you and me.
#include <bits/stdc++.h>
#define ET return 0
#define fi first
#define se second
#define mp make_pair
#define pb emplace_back
#define ll long long
#define ull unsigned long long
#define inf INT_MAX
#define uinf INT_MIN
#define pii pair<int,int>
#define pll pair<ll,ll>
#define debug puts("--------Chery AK IOI--------");
#define fr1(i,a,b) for(int i=a;i<=b;i++)
#define fr2(i,a,b) for(int i=a;i>=b;i--)
#define fv(i,p) for(int i=0;i<p.size();i++)
#define ld long double
#define il inline
#define ptc putchar
//Quickly power: ll d=qpow(b,p>>1,k);
//Segment Tree: Memory Limit Excceed
//Segment Tree: Modify()->Pushdown()
//Mod: +M, %M, define int ll
//Mod: Don't use 998244353 instead of 1e9+7 and so on
//Don't solve a problem for too long time.
using namespace std;
/*
首先 容易得出充分必要条件:
我们把LH看成两种颜色
那就是找一个奇环,考虑奇环上的同色边(u,v),你需要先1->u,再u->v即可

那么你考虑去掉同色边做一个导出子图
那么你枚举所有同色边 考虑是否存在一条简单路径1->u->v
因为你不能经过相同的点,所以说考虑点双
你考虑建1为根的圆方树

假设u,v都不是割点,也就是在点双内->方点
那么你考虑u,v在圆方树上必然是祖先关系(这样显然可以1->u->v)
如果不这样,那么你就要从一个方点向上走
因为圆方树上只有圆方边,所以从方点出来就要经历圆点,这个点进去的时候走过一遍了
这就寄了

讨论一下u,v是割点的情况可以发现,把它们挂到自己圆方树上父亲就行了

这样是容易思考的

这里写了一个边双做法:

你考虑DFS树
那么你考虑 如果u,v在DFS树上是祖先关系
那肯定没问题对吧
反之你发现
因为u->v存在一条固有路径是树边
而DFS树没有横叉边
所以你要u->v就必须盖掉树边
那么存在从u,v连到LCA之上的返祖边才会有解
这样的话你等价于可以不经过u->v的树上路径抵达u/v
于是LCA的父亲和u/v一定在一个边双里面(说明树边都不是割边,可以不走任何树边抵达u/v)
对完了。
*/
const int N=2e5+10;
int tc;
int n,m;
char s[N];
int head[N<<1],to[N<<1],nxt[N<<1];
int _;
void add(int u,int v){
    _++;
    nxt[_]=head[u];
    head[u]=_;
    to[_]=v;
    // cout<<"!"<<u<<" "<<v<<endl;
    // cout<<nxt[_]<<endl;
}
vector <pii> spc;
vector <int> t[N];
int tot,tpt;
bool vis[N];
int dfn[N],low[N];
int bel[N];
bool bridge[N];
int dep[N],f[N][19];
int dis[N];
void dfs(int x,int e){
    // cout<<x<<" "<<e<<endl;
    tot++;
    dfn[x]=low[x]=tot;
    for(int i=head[x];~i;i=nxt[i]){
        if((i^1)==e) continue;
        int y=to[i];
        // cout<<i<<" "<<y<<"?"<<endl;
        if(!dfn[y]){
            t[x].pb(y);
            dfs(y,i);
            // cout<<x<<"->"<<y<<endl;
            low[x]=min(low[x],low[y]);
            if(low[y]==dfn[y]){
                // cout<<"!"<<endl;
                bridge[i]=bridge[i^1]=1;
                dis[y]++;
            }
        }
        else low[x]=min(low[x],low[y]);
    }
}
void cut(int x,int c){
    bel[x]=c;
    vis[x]=1;
    for(int i=head[x];~i;i=nxt[i]){
        int y=to[i];
        if(vis[y]||bridge[i]) continue;
        cut(y,c);
    }
}
void init(int x,int fa){
    f[x][0]=fa;
    dep[x]=dep[fa]+1;
    for(auto y:t[x]){
        dis[y]+=dis[x];
        init(y,x);
    }
}
int LCA(int x,int y){
    if(dep[x]<dep[y]) swap(x,y);
    int k=dep[x]-dep[y];
    fr2(i,18,0){
        if(k>=(1<<i)) k-=(1<<i),x=f[x][i];
    }
    if(x==y) return x;
    fr2(i,18,0){
        if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    }
    return f[x][0];
}
void clear(){
    fr1(i,1,n) dfn[i]=0;
    fr1(i,1,n) vis[i]=0;
    fr1(i,1,_) bridge[i]=nxt[i]=0;
    fr1(i,1,n) head[i]=-1;
    fr1(i,1,n) t[i].clear();
    _=1;
    tot=tpt=0;
    spc.clear();
}
void solve(){
    cin>>n>>m;
    clear();
    fr1(i,1,n) cin>>s[i];
    fr1(i,1,m){
        int u,v;
        cin>>u>>v;
        u++,v++;
        if(s[u]!=s[v]) add(u,v),add(v,u);
        else spc.pb(mp(u,v));
    }
    dfs(1,0);
    fr1(i,1,n){
        if(dfn[i]&&!vis[i]){
            tpt++;
            cut(i,tpt);
        }
    }
    // fr1(i,1,n) cout<<bel[i]<<" ";
    // cout<<endl;
    init(1,1);
    fr1(j,1,18){
        fr1(i,1,n) f[i][j]=f[f[i][j-1]][j-1];
    }
    for(auto i:spc){
        int u=i.fi,v=i.se;
        if(!dfn[u]||!dfn[v]) continue;
        int lca=LCA(u,v);
        // cout<<u<<" "<<v<<" "<<lca<<endl;
        // cout<<tpt<<endl;
        if(u==lca||v==lca) return cout<<"yes\n",void();
        if(lca==1) continue;
        if(bel[u]==bel[f[lca][0]]||bel[v]==bel[f[lca][0]]) return cout<<"yes\n",void();
    }
    cout<<"no\n";
}
// #define Ltp cute
int main(){
#ifdef Ltp
	freopen("travel.in","r",stdin);
	freopen("travel.out","w",stdout);
#endif
    ios::sync_with_stdio(false);
    cin>>tc;
    while(tc--) solve();
	ET;
}
//ALL FOR Zhang Junhao.