SWUST OJ 1076: 判断给定有向图是否存在回路

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;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值