迷宫城堡

来源:互联网 发布:oracle数据库日志位置 编辑:程序博客网 时间:2024/06/08 15:14

为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A房间和B房间,只说明可以通过这个通道由A房间到达B房间,但并不说明通过它可以由B房间到达A房间。Gardon需要请你写个程序确认一下是否任意两个房间都是相互连通的,即:对于任意的i和j,至少存在一条路径可以从房间i到房间j,也存在一条路径可以从房间j到房间i。

题解:题目判断是否为强连通即可。因此用2次DFS即可。第二次将所有边的反转过来即可。就是第一次dfs判断出一个点是否能到其他所有的点。反转过来后,能够再进行同样的dfs,会是判断其他所有的边是否能到这个点。如果都可以,就是强连通的。如果有一个点不能到达,就表示不为强连通,因为这个点通过其他点也到不了那个点。




#include<iostream>
#include<stack>
#include<vector>
#include<cstring>
using namespace std;
const int max_N = 10005;
vector<int> sum[max_N];
vector<int>f_sum[max_N];
bool used[max_N];
int N;
stack<int> sta;
bool dfs(vector<int>*k) {
for (int i = 0;i < max_N;i++)used[i] = false;
sta.push(1);
used[1] = true;
int count = 0;
while (!sta.empty()) {
int node = sta.top();
count++;
sta.pop();
for (int i = 0;i < k[node].size();i++) {
if (used[k[node][i]])continue;
sta.push(k[node][i]);
used[k[node][i]] = true;
}
}
if (count == N)return true;
else return false;
}
void fanxiang() {
for (int i = 1;i <= N;i++) {
for (int j = 0;j < sum[i].size();j++) {
f_sum[sum[i][j]].push_back(i);
}
}
}
int main() {
int m;
while (cin >> N >> m) {
if (N == 0 && m == 0)break;
for (int i = 1;i <=N;i++) {
sum[i].clear();f_sum[i].clear();
}
for (int i = 0;i < m;i++) {
int a, b;
cin >> a >> b;
sum[a].push_back(b);
}
if (!dfs(sum)) {
cout << "No" << endl;continue;
}
fanxiang();
if (!dfs(f_sum)) {
cout << "No" << endl;continue;
}
cout << "Yes" << endl;
}
return 0;
}

原创粉丝点击