NC214903. TravelingMerchant
描述
输入描述
There are several test cases. The first line contains a positive integer indicating the number of test cases. Each test case begins with two positive integers and indicating the number of cities and the number of roads.
The next line is a string of length containing or . The -th () charactor of is if the starting price at city is . The -th () charactor of is if the starting price at city is .
The -th line () of the following lines contains two different cities and , indicating a road between and .
The sum of the values of over all test cases is no more than . The sum of the values of over all test cases is no more than . For each test case, holds for each . is always . and hold for each . No two roads connect the same pair of cities.
输出描述
For each test case, output a line of "yes" or "no", indicating whether there exists an endless earning path.
示例1
输入:
2 4 4 LHLH 0 1 1 2 1 3 2 3 3 3 LHH 0 1 0 2 1 2
输出:
yes no
说明:
In the first sample test case, the endless earning path is . In the illustration, cities with price are filled with stripe.C++(clang++11) 解法, 执行用时: 230ms, 内存消耗: 74104K, 提交时间: 2021-01-23 13:05:35
#include<bits/stdc++.h> using namespace std; #define N 400005 #define pb push_back int T,n,m,cntV,dfn[N],low[N],fa[N],st[N],sz[N]; char a[N];vector<int> e1[N],e2[N]; struct Edge {int u,v;}e[N]; void Tarjan(int u,int f) { dfn[u]=low[u]=++dfn[0];st[++st[0]]=u; for(int i=0,v;i<e1[u].size();++i) { v=e1[u][i];if(v==f) continue; if(!dfn[v]) { Tarjan(v,u);low[u]=min(low[u],low[v]); if(low[v]>=dfn[u]) { e2[u].pb(++cntV);e2[cntV].pb(u);e2[v].pb(cntV);e2[cntV].pb(v); while(st[st[0]]!=v) e2[st[st[0]]].pb(cntV),e2[cntV].pb(st[st[0]--]);--st[0]; } }else low[u]=min(low[u],dfn[v]); } } void dfs(int u,int f) { dfn[u]=++dfn[0];sz[u]=1;fa[u]=f; for(int i=0,v;i<e2[u].size();++i) {v=e2[u][i];if(!dfn[v]) dfs(v,u),sz[u]+=sz[v];} } void slv() { scanf("%d %d %s",&n,&m,a+1); for(int i=1;i<=cntV;++i) e2[i].clear();cntV=n; dfn[0]=0;for(int i=1;i<=n;++i) dfn[i]=0,e1[i].clear(); for(int i=1,u,v;i<=m;++i) { scanf("%d %d",&u,&v);++u;++v;e[i]=(Edge) {u,v}; if(a[u]^a[v]) e1[u].pb(v),e1[v].pb(u); }Tarjan(1,0);for(int i=1;i<=cntV;++i) dfn[i]=sz[i]=0;dfs(1,0); for(int i=1,u,v;i<=m;++i) if(a[e[i].u]==a[e[i].v]) { u=e[i].u;v=e[i].v;if(!dfn[u] || !dfn[v]) continue; if(u==1 || v==1) {puts("yes");return;}u=fa[e[i].u];v=fa[e[i].v]; if(dfn[u]>=dfn[v] && dfn[u]<dfn[v]+sz[v]) {puts("yes");return;} if(dfn[v]>=dfn[u] && dfn[v]<dfn[u]+sz[u]) {puts("yes");return;} }puts("no"); } int main() {scanf("%d",&T);while(T--) slv();}