Going from u to V or from V to u?
| Time limit:2000 ms |
|
Memory limit:65536 K |
| Total submissions:14469 |
|
Accepted:3801 |
Description
In order to make their sons brave, Jiajia and wind take them to a big cave. the cave has n rooms, and one-way corridors connecting some rooms. each time, wind choose two rooms X and Y, and ask one of their little sons go from one to the other. the son can either go from X to Y, or from Y to X. wind promised that her tasks are all possible, but she actually doesn' t know how to decide if a task is Po Ssible. to make her life easier, Jiajia decided to choose a cave in which every pair of rooms is a possible task. given a cave, can you tell Jiajia whether wind can randomly choose two rooms without worrying about anything?
Input
The first line contains a single integer t, the number of test cases. And followed t cases.
The first line for each case contains two integers n, m (0 <n <1001, m <6000), the number of rooms and corridors in the cave. the next M lines each contains two integers U and V, indicating that there is a corridor connecting room U and Room V directly.
Output
The output shoshould contain t lines. Write 'yes' if the cave has the property stated above, or 'no' otherwise.
Sample Input
13 31 22 33 1
Sample output
Yes
Source
Poj monthly -- 2006.02.26, zgl & twb
Question:
T group test data, n vertices, M has a directed edge, and then asks if this graph meets any two vertices u to V or V to u
Solution:
Refer to my blog this article, you will know the solution: http://blog.csdn.net/a1061747415/article/details/38380665
Solution code:
#include <iostream>#include <cstdio>#include <cmath>#include <vector>#include <algorithm>using namespace std;const int maxn=1100;const int maxm=51000;struct edge{ int u,v,next; edge(int u0=0,int v0=0){ u=u0;v=v0; }}e[maxm];int n,m,head[maxn],dfn[maxn],low[maxn],mark[maxn],w[maxn],color[maxn],dp[maxn],cnt,nc,index;vector <int> vec;vector <vector<int> > dfsmap;void addedge(int u,int v){ e[cnt]=edge(u,v);e[cnt].next=head[u];head[u]=cnt++;}void input(){ cnt=nc=index=0; scanf("%d%d",&n,&m); vec.clear(); for(int i=0;i<=n;i++){ w[i]=dfn[i]=0; mark[i]=false; color[i]=dp[i]=head[i]=-1; } int u,v; while(m-- >0){ scanf("%d%d",&u,&v); addedge(u,v); }}void tarjan(int s){ dfn[s]=low[s]=++index; mark[s]=true; vec.push_back(s); for(int i=head[s];i!=-1;i=e[i].next){ int d=e[i].v; if(!dfn[d]){ tarjan(d); low[s]=min(low[d],low[s]); }else if(mark[d]){ low[s]=min(low[s],dfn[d]); } } if(dfn[s]==low[s]){ nc++; int d; do{ d=vec.back(); vec.pop_back(); color[d]=nc; mark[d]=false; w[nc]++; }while(d!=s); }}int DP(int s){ if(dp[s]!=-1) return dp[s]; int ans=w[s]; for(int i=0;i<dfsmap[s].size();i++){ int d=dfsmap[s][i]; if(DP(d)+w[s]>ans) ans=DP(d)+w[s]; } return dp[s]=ans;}void solve(){ for(int i=1;i<=n;i++){ if(!dfn[i]) tarjan(i); } dfsmap.clear(); dfsmap.resize(nc+1); for(int i=0;i<cnt;i++){ int x=color[e[i].u],y=color[e[i].v]; if(x!=y){ dfsmap[x].push_back(y); //cout<<x<<"->"<<y<<endl; } } int ans=0; for(int i=1;i<=nc;i++){ if(DP(i)>ans) ans=DP(i); //cout<<i<<" "<<ans<<endl; } if(ans>=n) printf("Yes\n"); else printf("No\n");}int main(){ int t; scanf("%d",&t); while(t-- >0){ input(); solve(); } return 0;}