为什么打算重新写一下呢,因为最近一直在做并查集的题.emmm/
现在讲两种dfs判断环的方式.
对于无向图只需对另一一个点做一次dfs即可,因为任意一个点一定可以都到的.
int vis[N];
void dfs(int u,int fa)//判断有没有环.
{
if(vis[u]) {flag=1;return;}
vis[u]=1;
for(int i=0;i<v[u].size();i++)
{
if(v[u][i]==fa) continue;
dfs(v[u][i],u);
}
}//对于单个联通的无向图直接dfs一次即可.对于有向图呢?
有向图做法和无向图做法大同小异.你的vis数组存3个状态即可,因为不确定树根是否能遍历到环,我们用3个vis状态可以写...
用vis[i]=1,表示前面的点可以遍历到这个点且没产生环,那么,显然的一个结论,我下次遍历这个点是毫无意义的,vis[i]=0,表示我正在遍历的点,假如我正在遍历的点下次还遍历到了,那么肯定这就有环了,否则就遍历儿子,最后把vis[i]=1,然后枚举其他节点为根,复杂度是O(N)的.
#include <bits/stdc++.h>
using namespace std;
const int N=2e4+5;
vector<int>v[N];
int vis[N];
bool dfs(int u)
{
vis[u]=0;
for(int i=0;i<v[u].size();i++)
{
if(vis[v[u][i]]==0) return true;
if(vis[v[u][i]]==-1&&dfs(v[u][i])) return true;
}
vis[u]=1;
return false;
}
int main()
{
int n,m;//n个点m条边.
cin>>n>>m;
memset(vis,-1,sizeof vis);
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
v[x].push_back(y);
}int flag=0;
for(int i=1;i<=n;i++)
{
if(vis[i]==-1)
{
if(dfs(i)) flag=1;
}
}
flag==1?puts("yes"):puts("no");
return 0;
}我们再来看这个题目,给定大小关系要你判断有没有矛盾...2333
对于=我们可以建一个并查集,直接用祖先代表它的关系,对于>我们可以把大的和小的建一条有向边,除此之外,这个题就变成了给你一幅有图,要你判断图中是否有环因为方向不能错哈.代码就很简单了2333
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int fa[N],id,vis[N];
struct vv{
int from,to;
}a[N];
int f(int x)
{
if(x==fa[x]) return x;
else return fa[x]=f(fa[x]);
}
void init()
{
for(int i=0;i<=N-5;i++) fa[i]=i;
memset(vis,-1,sizeof vis);
}
vector<int>v[N];
bool dfs(int u)
{
vis[u]=0;
for(int i=0;i<v[u].size();i++)
{
if(vis[v[u][i]]==0) return true;
if(vis[v[u][i]]==-1&&dfs(v[u][i])) return true;
}
vis[u]=1;
return false;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
init();
for(int i=1;i<=m;i++)
{
int x,y;char c;
cin>>x>>c>>y;
if(c=='=')
{
if(f(x)!=f(y))
{
fa[f(x)]=f(y);
}
}
else if(c=='>')
{
a[++id]={x,y};
}
else
{
a[++id]={y,x};
}
}
for(int i=1;i<=id;i++)
{
v[f(a[i].from)].push_back(f(a[i].to));
}
int flag=0;
for(int i=0;i<n;i++)
{
if(vis[i]==-1)
{
if(dfs(i)) flag=1;
}
}
if(flag) puts("inconsistent");
else puts("consistent");
return 0;
}
坑点在点是5e4,边大于5e4,数组开5e4报wa,导致debug很久...emmm/

京公网安备 11010502036488号