建立正向图和反向图,分别沿着两个方向遍历,中途不改变方向,然后查看每个点是否能被其中一个方向遍历的过程中走到
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1e3 + 5, M = 1e4 + 5;
int h[N][2], e[M][2], ne[M][2], cnt[2];
int st[N][2];
void add(int u, int v, int type)
{
e[++cnt[type]][type] = v;
ne[cnt[type]][type] = h[u][type];
h[u][type] = cnt[type];
}
void dfs(int u, int type)
{
for (int i = h[u][type]; i; i = ne[i][type])
{
int v = e[i][type];
if (!st[v][type])
{
st[v][type] = 1;
dfs(v, type);
}
}
}
bool check(int n)
{
for (int i = 1; i <= n; ++i)
if (!st[i][0] && !st[i][1]) return false;
return true;
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
while (m--)
{
int u, v;
scanf("%d%d", &u, &v);
add(u, v, 0), add(v, u, 1);
}
int ret = 0;
for (int i = 1; i <= n; ++i)
{
memset(st, 0, sizeof st);
st[i][0] = st[i][1] = 1;
dfs(i, 0), dfs(i, 1);
if (check(n)) ret++;
}
printf("%d", ret);
return 0;
}
请问这题时间复杂度怎么算呀,是O(n^2 m)吗,那这样怎么没超时呀
O(n^2)
以每个点为起点遍历,一次遍历最多O(n)
哦哦哦,我傻了,搞成嵌套关系了,谢谢大佬!
为什么O(n^2)啊。
我感觉dfs是O(m)啊,遍历边
st数组限制了原来访问过的就不接着访问了,所以每个节点访问一次,因此是$\mathcal{O}(n)$
add中为什么最后 cnt 没有 ++ 呢
add函数里,第一句e[++cnt]
我这里cnt下标是从1开始的,可能和y总的模板有点不一样
就相当于我添加边的关系时,先++cnt,然后在填入边的关系
谢谢
想问一下这里为什么add这里最后cnt没有,但是第一步存点时候了?我按给出模板写,最后cnt++,写出来不对