CCF201709-4通信网络_双向DFS

这题一看, 如果不考虑时间的话, 用floyd算法求传递闭包和对称闭包是可以解决的, 但是题目的数据只够过60分, 正解显然不是这样.

然后我又思考, 开始往复杂了想, 于是有了下面的不知对错的思路:

先判断图是否连通,否则结果为0
用tarjan算法缩点, 把环全都合成一个结点,他们的处境是一样的
找到一个入度为0的结点,(缩点之后一定存在), 它会指向好几个点, 找出它指向点的共同点, 不断找直到共同指向
一个点. 寻找过程中每个唯一的聚合点就是结果点

不仅实现起来难, 而且思路是否正确还存疑. 毕竟我还没有掌握强连通分量缩点的算法.

然后投降了, 找找博客吧, 找到的第一篇博客居然就用了缩点的算法! 然后看其他博客, 发现他们的共同点都是用了DFS. WTF? 这题能用DFS? 不会超时吗? 于是我开始考虑DFS, 确实不会超时, 时间复杂度是O(NM).

这里暴露出我的一个问题, 我的潜意识里面认为DFS就是递归嘛, 递归都是很慢的嘛, 所以直接用DFS很容易超时的嘛. 然而并不! 所以遇到问题还是应该具体分析下时间, 不要被自己的潜意识误导, 从而错过正确的思路.

下面是DFS思路, 准确来说是双向DFS
  • 在有向图中, 对于一个点, 它的DFS遍历可达的点是它可传递信息的点.
  • 它的反向DFS遍历(边的方向反转)可达的点是可传递信息到它的点.
  • 那么我们获取这两种点, 如果这两种点集包含除自己以外的所有点, 那么答案+1.

就是这么简单的思路, 双向DFS, 找到可传递信息的所有点. 需要注意的是, 这里不应该在遍历的过程中找到点就cnt++, 因为前后遍历可能会出现重复的点(双向), 就会出错. 正确方法应该是记录这些可达的点, 然后用hash的方法去统计.

最后此题学到的一个小经验就是存图的时候还是尽量用邻接表吧, 用起来也方便, 而且不容易超时! 不容易超时! 不容易超时!
100分代码

#include <algorithm>
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

const int maxn = 1005;
vector<int> Gp[maxn], Gs[maxn], to[maxn];
int n, m, vis[maxn], ans = 0;

void DFS(vector<int> G[maxn], int u, int scr)
{
    for (int i = 0; i < G[u].size(); ++i) {
        if (!vis[G[u][i]]) {
            vis[G[u][i]] = true;
            DFS(G, G[u][i], scr);
        }
    }
    to[scr].push_back(u);
}

int main()
{
    cin >> n >> m;
    for (int i = 0, u, v; i < m; ++i) {
        cin >> u >> v;
        Gp[u - 1].push_back(v - 1);
        Gs[v - 1].push_back(u - 1);
    }
    for (int i = 0; i < n; ++i) {
        memset(vis, 0, sizeof(vis));
        DFS(Gp, i, i);
    }
    for (int i = 0; i < n; ++i) {
        memset(vis, 0, sizeof(vis));
        DFS(Gs, i, i);
    }
    for (int i = 0; i < n; ++i) {
        memset(vis, 0, sizeof(vis));
        for (int j = 0; j < to[i].size(); ++j) {
            vis[to[i][j]] = 1;
        }
        bool flag = false;
        for (int j = 0; j < n; ++j) {
            if (vis[j] == 0) flag = true;
        }
        if (flag == false) ans++;
    }
    cout << ans;
}

猜你喜欢

转载自blog.csdn.net/wjh2622075127/article/details/81448749