QOJ.ac
QOJ
ID | Submission ID | Problem | Hacker | Owner | Result | Submit time | Judge time |
---|---|---|---|---|---|---|---|
#771 | #508272 | #8029. Traveling Merchant | Shunpower | Shunpower | Success! | 2024-08-07 20:24:54 | 2024-08-07 20:24:54 |
Details
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 | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#508272 | #8029. Traveling Merchant | Shunpower | WA | 121ms | 59772kb | C++14 | 5.0kb | 2024-08-07 12:03:56 | 2024-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.