1076: 判断给定有向图是否存在回路
题目链接-1076: 判断给定有向图是否存在回路
解题思路
拓
扑
排
序
拓扑排序
拓扑排序
- 先统计所有节点的入度,对于入度为0的节点就可以分离出来,即将所有入度为0的顶点放入队列
- 然后把这个节点指向的节点的入度减1,直到所有的节点都被分离出来
- 如果最后不存在入度为0的节点,那就说明有环(即回路),不存在拓扑序列
- 伪代码:
附上代码
//#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
#define lowbit(x) (x &(-x))
#define endl '\n'
using namespace std;
const int INF=0x3f3f3f3f;
const int dir[4][2]={-1,0,1,0,0,-1,0,1};
const double PI=acos(-1.0);
const double e=exp(1.0);
const double eps=1e-10;
const int M=1e9+7;
const int N=2e5+10;
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ull;
int n,m;
char a[1010];
int edge[30][30],in[30];
vector<int> v;
queue<int> q;
void topsort(){//拓扑排序
for(int i=1;i<=n;i++)
if(!in[a[i]-'A'])
q.push(a[i]-'A');//将所有入度为0的顶点放入队列
while(!q.empty()){
int x=q.front();
q.pop();//选一个入度为0的点出队列
v.push_back(x);
for(int i=1;i<=n;i++){//删除所有与x顶点有关的边
if(edge[x][a[i]-'A']){//遍历当前点能到的所有点,能到的入度都减去1
in[a[i]-'A']--;//邻接点入度减一
if(!in[a[i]-'A'])
q.push(a[i]-'A');
}
}
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
while(m--){
char u,v;
cin>>u>>v;
edge[u-'A'][v-'A']=1;//连边构图
in[v-'A']++;//记录入度
}
topsort();
if(v.size()<n)
cout<<"yes";
else
cout<<"no";
return 0;
}