CCF-CSP 201709-4通信网络 满分题解
题目链接:201709-4通信网络
思路:
1. 需要判断一个点能否和其他所有点的联系起来,则可以创建两个类型的图,即正向图(判断该点可以到达的点的数目)和反向图(判断该点可以被其他点到达的数目);
2. 通过dfs搜索,判断该点能否到达其他点;
具体代码如下:
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
const int N = 1e5+10;
int h[N][2],e[N][2],ne[N][2],idx[2];//采用邻接表的形式存储图的信息
int n,m;
bool st[N][2];//判断点是否遍历过
void add(int a, int b,int type)//向邻接表中插入边
{
e[idx[type]][type]=b;
ne[idx[type]][type]=h[a][type];
h[a][type]=idx[type]++;
}
void dfs(int u,int type)//深搜判断
{
st[u][type]=true;
for(int i = h[u][type];i!=-1;i=ne[i][type])
{
int t=e[i][type];
if(!st[t][type])
{
dfs(t,type);
}
}
}
int main()
{
memset(h, -1, sizeof(h));
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int a,b;
cin>>a>>b;
//向正顺序图和逆顺序图中插入边
add(a,b,0);
add(b,a,1);
}
int sum=0;
//对每个点进行遍历
for(int i=1;i<=n;i++)
{
int t = 0;//可以遍历的点的个数
//将点初始化
for(int j=1;j<=n;j++)
{
st[j][1]=false;
st[j][0]=false;
}
dfs(i,1);
dfs(i,0);
//判断该点是否符合要求,即正顺序和逆顺序加起来的结果可以遍历所有点
for(int j=1;j<=n;j++)
{
if(st[j][0]==true||st[j][1]==true)//正向和逆向满足其一即可
t++;
}
if(t>=n)sum++;
}
cout<<sum<<endl;
return 0;
}