您的位置:首页 > 大数据 > 人工智能

1008. Airline Routes (35)解题报告

2017-01-17 02:10 309 查看
首先感谢神赐予我智慧和力量。

我先通过DFS把图分解为若干个强连通分量,然后用并查集区分每个强连通分量。查询时,只要找并查集的根就可以了。这种方法来自《算法导论》22.5强连通分量。划分强连通分量的时间复杂度为O(V+E),查询的时间复杂度为O(K)。

用DFS标记出每个结点的结束时间。
按照结束时间降序,对逆邻接表进行DFS。
单独一次DFS所遍历的结点就是某一个强连通分量的所有成员。
在第二次DFS时,把同一个强连通分量的结点归并到同一个集合里。

在解题过程中,我也参阅了下面这篇博文:
PAT (Top Level) Practise 1008 Airline Routes (35) - 程序园



#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <stack>
using namespace std;
const int N = 10003;
void dfs(vector<int> city[], int index);
void dfs(vector<int> city[], int index, int cityset[]);
int findroot(int cityset[], int index);
void setunion(int cityset[], int index1, int index2);
stack<int> s;
bool visit
;
int finish
;
int main(void) {
int n, m, k, i, source, dest, *cityset;
vector<int> *city, *cityt;
setvbuf(stdin, new char[1 << 20], _IOFBF, 1 << 20);
setvbuf(stdout, new char[1 << 20], _IOFBF, 1 << 20);
scanf("%d %d", &n, &m);
cityset = new int[n + 1];
city = new vector<int>[n + 1];
cityt = new vector<int>[n + 1];
for (i = 0; i < n + 1; i++) {
cityset[i] = -1;
}
for (i = 0; i < m; i++) {
scanf("%d %d", &source, &dest);
city[source].push_back(dest);
cityt[dest].push_back(source);
}
for (i = 1; i <= n; i++) {
if (!visit[i]) {
dfs(city, i);
}
}
memset(visit, 0, N * sizeof(bool));
for (i = n; i > 0; i--) {
if (!visit[finish[i]]) {
dfs(cityt, finish[i], cityset);
}
}
scanf("%d", &k);
for (i = 0; i < k; i++) {
scanf("%d %d", &source, &dest);
int root1 = findroot(cityset, source), root2 = findroot(cityset, dest);
if (root1 != -1 && root1 == root2) {
puts("Yes");
}
else {
puts("No");
}
}
delete[] city;
delete[] cityt;
delete[] cityset;
return 0;
}

void dfs(vector<int> city[], int index, int cityset[]) {
int i;
visit[index] = true;
s.push(index);
for (i = 0; i < (int) city[index].size(); i++) {
if (!visit[city[index][i]]) {
setunion(cityset, index, city[index][i]);
dfs(city, city[index][i], cityset);
}
}
s.pop();
return;
}

void dfs(vector<int> city[], int index) {
int i;
static int cnt = 0;
visit[index] = true;
s.push(index);
for (i = 0; i < (int) city[index].size(); i++) {
if (!visit[city[index][i]]) {
dfs(city, city[index][i]);
}
}
cnt++;
finish[cnt] = index;
s.pop();
return;
}
int findroot(int cityset[], int index) {
if (cityset[index] < 0) {
return index;
}
else {
return cityset[index] = findroot(cityset, cityset[index]);
}
}
void setunion(int cityset[], int index1, int index2) {
int root1, root2;
root1 = findroot(cityset, index1);
root2 = findroot(cityset, index2);
if (root1 == root2) {
return;
}
if (cityset[root1] < cityset[root2]) {
cityset[root1] += cityset[root2];
cityset[root2] = root1;
}
else {
cityset[root2] += cityset[root1];
cityset[root1] = root2;
}
return;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: