点击前往试题目录:https://blog.csdn.net/best335/article/details/99550556
题意:从图中找出点S使得S能到达所有的点,或所有的点能到达S,也即它的逆图能到达所有的点。求S的个数。
按照我理解的题意求解得到的结果是错的,不晓得错在哪里,我之前做过这道题
此段代码为错误代码
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
int n,m,V[1001],ans;
vector<int> G[2][1001];//G[1]为G[0]的逆图
void DFS(const int&u,const int&p){
V[u]=1;
for(int i=0,ni=G[p][u].size();i<ni;++i) if(V[G[p][u][i]]==0) DFS(G[p][u][i],p);
}
int main(){
cin>>n>>m,ans=0;
for(int i=0,a,b;i<m;++i)cin>>a>>b,G[0][a].emplace_back(b),G[1][b].emplace_back(a);
for(int i=n;i>0;--i)
for(int p=0,k;p<2;++p){
memset(V,0,sizeof(V)),DFS(i,p);
for(k=n;k>0&&V[k]==1;--k);//计算到达了所有点
if(k==0)++ans,p=2;//如果到达了所有点退出这层循环 否则尝试它的逆图是否能到达所有点
}
cout<<ans<<endl;
return 0;
}
//AC代码
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
int n,N,m,ans;
vector<int>G[1001];//图G
char V[1001],M[1001][1001],F=char(0),T=char(1);//每次DFS的访问标志V 可达标记M
void DFS(const int&u,const int&v){//起点是u,可以到达的点v
M[u][v]=M[v][u]=V[v]=T;
for(int i=0,ni=G[v].size();i<ni;++i) if(V[G[v][i]]==F) DFS(u,G[v][i]);
}
int main(){
cin>>n>>m,ans=0,N=n+1,memset(M,0,sizeof(M));//输入 初始化
for(int i=0,a,b;i<m;++i)cin>>a>>b,G[a].emplace_back(b);//输入
for(int i=n;i>0;--i) M[i][0]=T,memset(V,0,sizeof(char)*N),DFS(i,i);//暴力DFS
for(int i=n;i>0;--i)if(string(N,T)==string(M[i],N))++ans;//判断是否能到达所有点
cout<<ans<<endl;
return 0;
}