传递闭包问题
(a->b&&b->c)--->(a->c)
图的表示最好用邻接链表的方式。
floyd
这样做是超时的。
#include <iostream>
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <assert.h>
#include <queue>
using namespace std;
const int MAXSIZE = 1005;
bool road[MAXSIZE][MAXSIZE];
int n, m;
int main() {
memset(road, 0, sizeof(road));
cin >> n >> m;
int a, b;
for (int i = 0; i < m; ++i) {
cin >> a >> b;
a--, b--;
road[a][b] = true;
}
for (int i = 0; i < n; ++i) {
road[i][i] = true;
}
// 求传递闭包
for (int k = 0; k < n; ++k) {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (i == j || i == k || j == k) continue;
if (road[i][k] && road[k][j]) {
road[i][j] = true;
}
}
}
}
int ans = 0;
for (int i = 0; i < n; ++i) {
int sum = 0;
for (int j = 0; j < n; ++j) {
if (road[i][j] || road[j][i])
sum++;
}
if (sum == n)
ans++;
}
cout << ans << endl;
}
正反BFS仍然超时
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <queue>
#include <cstring>
using namespace std;
const int MAXSIZE = 1010;
bool road[MAXSIZE][MAXSIZE];
bool fakeroad[MAXSIZE][MAXSIZE];
bool visit[MAXSIZE];
bool connect[MAXSIZE][MAXSIZE];
int n, m;
int main() {
// freopen("../in.txt", "r", stdin);
cin >> n >> m;
int a, b;
for (int i = 0; i < m; ++i) {
cin >> a >> b;
a--, b--;
road[a][b] = true;
fakeroad[b][a] = true;
}
queue<int> Q;
for (int i = 0; i < n; ++i) {
memset(visit, 0, sizeof(visit));
visit[i] = true;
Q.push(i);
while (!Q.empty()){
int temp = Q.front();
Q.pop();
for (int j = 0; j < n; ++j) {
if (!visit[j]&&road[temp][j]){
visit[j] = true;
Q.push(j);
connect[i][j] = true;
}
}
}
}
for (int i = 0; i < n; ++i) {
memset(visit, 0, sizeof(visit));
visit[i] = true;
Q.push(i);
while (!Q.empty()){
int temp = Q.front();
Q.pop();
for (int j = 0; j < n; ++j) {
if (!visit[j]&&fakeroad[temp][j]){
visit[j] = true;
Q.push(j);
connect[i][j] = true;
}
}
}
}
int ans = 0;
for (int i = 0; i < n; ++i) {
bool flag = true;
for (int j = 0; j < n; ++j) {
if (i == j) continue;
if (!connect[i][j])
flag = false;
}
if (flag)
ans++;
}
cout << ans << endl;
}
邻接链表表示
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <queue>
#include <cstring>
using namespace std;
const int MAXSIZE = 1010;
vector<int > road[MAXSIZE];
vector<int > fakeroad[MAXSIZE];
bool visit[MAXSIZE];
bool connect[MAXSIZE][MAXSIZE];
int n, m;
int main() {
// freopen("../in.txt", "r", stdin);
cin >> n >> m;
int a, b;
for (int i = 0; i < m; ++i) {
cin >> a >> b;
a--, b--;
road[a].push_back(b);
fakeroad[b].push_back(a);
}
queue<int> Q;
for (int i = 0; i < n; ++i) {
memset(visit, 0, sizeof(visit));
visit[i] = true;
Q.push(i);
while (!Q.empty()){
int temp = Q.front();
Q.pop();
for (int j = 0; j < road[temp].size(); ++j) {
int k = road[temp][j];
if (!visit[k]){
visit[k] = true;
Q.push(k);
connect[i][k] = true;
}
}
}
}
for (int i = 0; i < n; ++i) {
memset(visit, 0, sizeof(visit));
visit[i] = true;
Q.push(i);
while (!Q.empty()){
int temp = Q.front();
Q.pop();
for (int j = 0; j < fakeroad[temp].size(); ++j) {
int k = fakeroad[temp][j];
if (!visit[k]){
visit[k] = true;
Q.push(k);
connect[i][k] = true;
}
}
}
}
int ans = 0;
for (int i = 0; i < n; ++i) {
bool flag = true;
for (int j = 0; j < n; ++j) {
if (i == j) continue;
if (!connect[i][j])
flag = false;
}
if (flag)
ans++;
}
cout << ans << endl;
}