Part 0 前言
本题的机翻是该改了,一言难尽。
本题较简单,建议评橙。
Part 1 题意
由于本题的机翻太过好看,在这里呈上我校内 OJ 的翻译。
Part 2 思路
很明显,我们可以用 Spfa 算法的不联通即初始值的特性,暴力枚举以每个点为源点的最短路,若原点到某个点的值为初始值,则不联通,用数组记录,然后遍历这个数组,若有两个节点互相不能到达,那么输出 No
,否则输出 Yes
,即可求解。
Part 3 AC Code
#include<bits/stdc++.h>
using namespace std;
int n,m,d[100005];
bool inq[100005];
int inf[1010][1010];
struct A{ int y,w; };
vector<A>a[100005];
queue<int>b;
inline void spfa(int v0){//spfa 算法
for(int i=1;i<=n;i++) d[i]=1e9;//初值为1e9
d[v0]=0;
b.push(v0);
while(!b.empty()){
int now=b.front();
b.pop();
for(auto x:a[now]){
if(d[x.y]>d[now]+x.w){
d[x.y]=d[now]+x.w;
if(!inq[x.y]) b.push(x.y);
}
}
}
}
int main(){
int t;
scanf("%d",&t);
while(t--){
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) inf[i][j]=0;//初始化记录数组
for(int i=1;i<=m+2;i++) a[i].clear();//初始化
scanf("%d%d",&n,&m);
int u,v;
for(int i=1;i<=m;i++){
scanf("%d%d",&u,&v);
a[u].push_back({v,1});//spfa建边
}
bool flag=true;
for(int i=1;i<=n;i++){
spfa(i);
for(int j=1;j<=n;j++){
if(d[j]==1e9) continue;//为初始值即不联通,continue掉
else inf[i][j]=1;
}
}//判断是否联通
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(inf[i][j]==0&&inf[j][i]==0) {//两个点互补联通,break掉
cout<<"No\n";
flag=false;
break;
}
}
if(!flag) break;
}
if(flag) cout<<"Yes\n";//否则输出Yes
}
return 0;
}