CCF 通信网络
题目的描述在这里
我最开始的思路是对的,就是正向和反向各做一遍DFS然后遍历统计一下有多少个点能与其他所有点联通。然而在这里我犯了一个错误,这个错误是题目中给出的例子对我的一个误导。
这个误导的内容就是说,能够连通所有点的情况并不是只有下图中的这种情况。
这种情况我们只要认为在某一种遍历里方式下,一个点与其他的所有点都联通就可以了。
但实际上,正向遍历和反向遍历只要能够互补就满足题目的要求了。让一个点与其他所有点都有连通关系的要求太过于严格(最多只能得25分·····)。因为题目中很有可能给的是这样的一张图
如果是这种情况的话,并不存在一个点能够在正向DFS或反向DFS后就直接能与所有点联通,但是正向与反向的是互补的,仍然能够满足题目中的要求。
代码如下
#include<iostream>
#include<vector>
#include<cstring>
#define MAX 1010
using namespace std;
vector<int>Map[MAX],Map1[MAX];
bool visit[MAX],visit1[MAX];
int m,n;
void DFS(int t,int begin) {
visit[t]=1;
for(int i=0; i<Map[t].size(); i++) {
int a=Map[t][i];
if(visit[a]==0)
DFS(a,begin);
}
};
void DFS1(int t,int begin) {
visit1[t]=1;
for(int i=0; i<Map1[t].size(); i++) {
int a=Map1[t][i];
if(visit1[a]==0)
DFS1(a,begin);
}
}
int main() {
freopen("sb.txt","r",stdin);
scanf("%d %d",&n,&m);
memset(visit,0,sizeof(visit));
for(int i=0; i<m; i++) {
int a,b;
scanf("%d %d",&a,&b);
Map[a].push_back(b);
Map1[b].push_back(a);
}
int ans=0;
for(int i=1; i<=n; i++) {
memset(visit,0,sizeof(visit));
memset(visit1,0,sizeof(visit1));
DFS(i,i);
DFS1(i,i);
int t1=0,t2=0;
int flag=1;
for(int j=1; j<=n; j++) {
if(visit[j]==0&&visit1[j]==0) {
flag=0;
break;
}
}
if(flag)ans++;
}
cout<<ans;
return 0;
}