Going from U to V or from V to U?
【题目描述】
现给定一幅有向图,选择两个点V和U,要求V能到达U或U能到达V。
询问对于图中的每一点对(V,U)是否都能满足条件,如果可以,输出“Yes”,否则,输出“No”。
【输入描述】
第一行输入一个正整数T,表示数据组数;
接下来输入T组数据,每组数据输入格式如下:
第一行输入两个整数n、m(0 < n < 1001,m < 6000),分别表示节点数和边数;
接下来m行,每行输入两个整数U、V,表示节点U和节点V之间存在一条有向边。
【输出描述】
对于每组输入数据,输出一行,包含一个“Yes”或“No”。
【输入样例】
1
3 3
1 2
2 3
3 1
【输出样例】
Yes
源代码: #include<cstdio> #include<cstring> #include<vector> #include<stack> #include<queue> using namespace std; vector <int> List[1001],Edge[1001]; stack <int> S; queue <int> Q; int T,n,m,Num,Number,i[1001],j[1001],Head[1001],InSum[1001]; bool In[1001]; void Tarjan(int T) //朴素Tarjan。 { i[T]=j[T]=++Num; S.push(T); In[T]=true; for (int a=0;a<List[T].size();a++) { int t=List[T][a]; if (!j[t]) { Tarjan(t); i[T]=min(i[T],i[t]); } else if (In[t]) i[T]=min(i[T],j[t]); } if (i[T]==i[T]) { int k; Number++; do { k=S.top(); Head[k]=Number; In[k]=false; S.pop(); } while (T!=k); } } bool Topsort() //拓扑排序。 { int Count(0); while (!Q.empty()) Q.pop(); for (int a=1;a<=Number;a++) if (!InSum[a]) { Count++; Q.push(a); } if (Count-1) return false; //存在一个以上入度为0的点,注意这是在求单连通分量。 while (!Q.empty()) //涨姿势了,利用队列实现。 { int T=Q.front(); Q.pop(); Count=0; for (int a=0;a<Edge[T].size();a++) { int t=Edge[T][a]; InSum[t]--; if (!InSum[t]) { Count++; Q.push(t); } } if (Count-1) return false; //同理于上。 } return true; } void Solve() { for (int a=1;a<=n;a++) if (!j[a]) Tarjan(a); memset(InSum,0,sizeof(InSum)); //InSum[]存储缩点后的入度数。 for (int a=1;a<=Number;a++) //这么多初始化真是,想婊人。 Edge[a].clear(); for (int a=1;a<=n;a++) for (int b=0;b<List[a].size();b++) //缩点重新建图。 { int t1=Head[a]; int t2=Head[List[a][b]]; if (t1!=t2) { InSum[t2]++; Edge[t1].push_back(t2); } } if (Topsort()) printf("Yes\n"); else printf("No\n"); } int main() //Tarjan缩点+拓扑排序。 { scanf("%d",&T); while (T--) { scanf("%d%d",&n,&m); Num=Number=0; //Num表示Tarjan序编号,Number表示缩点后的点数。 while (!S.empty()) //Tarjan栈。 S.pop(); for (int a=1;a<=n;a++) { List[a].clear(); //初始图。 j[a]=In[a]=0; //j[]存储时间戳,In[]表示是否入Tarjan栈。 } while (m--) { int t1,t2; scanf("%d%d",&t1,&t2); List[t1].push_back(t2); } Solve(); } return 0; }