ccf csp-201709-4-通信网络(dfs+有向图的遍历)

原试题点击此处

刚开始正反向dfs,只得了25分,后来参考dalao代码,发现可以将邻接表和领接矩阵相结合,邻接表用于存储图+dfs遍历(因为是有向图),领接矩阵则用于记录顶点与顶点之间的联系(换言之,将有向边转换为无向边存储),最终,如果该结点到其他任意结点都有边,则ans++,输出ans即可。

25分代码

#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
const int N = 1005;
int n,m,cnt = 0,visit[N]={0};
vector<int> v1[N],v2[N];
void dfs1(int num){
	cnt++;
	visit[num] = 1;
	for(int i = 0; i < v1[num].size(); i++){
		if(!visit[v1[num][i]]) dfs1(v1[num][i]);
	}
}
void dfs2(int num){
	cnt++;
	visit[num] = 1;
	for(int i = 0; i < v2[num].size(); i++){
		if(!visit[v2[num][i]]) dfs2(v2[num][i]);
	}
}
int main(){
	int a,b,ans = 0;
	scanf("%d%d", &n, &m);
	for(int i = 0; i < m; i++){
		scanf("%d%d", &a, &b);
		v1[a].push_back(b);
		v2[b].push_back(a);
	}
	for(int i = 1; i <= n; i++){
		cnt = 0;fill(visit,visit+N,0);
		dfs1(i);
		if(cnt == n) ans++;
	} 
	for(int i = 1; i <= n; i++){
		cnt = 0;fill(visit,visit+N,0);
		dfs2(i);
		if(cnt == n) ans++;
	} 
	printf("%d\n", ans);
	return 0;
}

AC代码

#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
const int N = 1005;
int n,m,cnt = 0,visit[N]={0};
int map[N][N];
vector<int> v[N];
void dfs(int a,int b){
	map[a][b] = 1;
	map[b][a] = 1;
	visit[a] = 1;
	for(int i = 0; i < v[a].size(); i++){
		if(!visit[v[a][i]]) dfs(v[a][i],b);
	}
}
int main(){
	int a,b,ans = 0,j;
	scanf("%d%d", &n, &m);
	for(int i = 0; i < m; i++){
		scanf("%d%d", &a, &b);
		v[a].push_back(b);
	}
	for(int i = 1; i <= n; i++){
		fill(visit,visit+N,0);
		dfs(i, i);
	} 
	for(int i = 1; i <= n; i++){
		for(j = 1; j <= n; j++){
			if(map[i][j] == 0) break;
		}
		if(j == n+1) ans++;
	}
	printf("%d\n", ans);
	return 0;
}
发布了118 篇原创文章 · 获赞 755 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_42437577/article/details/104364924