Description
给定一个有向图,判断该有向图是否存在一个合法的拓扑序列。
Input
输入包含多组,每组格式如下。
第一行包含两个整数n,m,分别代表该有向图的顶点数和边数。(n<=10)
后面m行每行两个整数a b,表示从a到b有一条有向边。
Output
若给定有向图存在合法拓扑序列,则输出YES;否则输出NO。
Sample
Input
1 0
2 2
1 2
2 1
Output
YES
NO
答案:
#include <iostream>
#include<bits/stdc++.h>
#define ll long long
const int N = 5e4 + 10;
using namespace std;
int mp[25][25]; //图的建立
int in[25]; //记录入度
int q[111]; //队列
int main()
{
int n,m;
while(cin>>n>>m)
{
memset(mp,0,sizeof(mp)); //数组清零
memset(in,0,sizeof(in)); //入度清零
int head=0,tail=0; //清空队列
while(m--) //图的建立
{
int a,b;
cin>>a>>b;
mp[a][b]=1; //a->b 单向联通
mp[a][b]=mp[b][a]=1; //a<->b双向联通
in[b]++; //b对应入度+1
}
int i;
for(i=1; i<=n; i++) //找到入度为零的点
{
if(!in[i])
{
q[tail++]=i; //入度为零的点入队
}
}
int cnt=0; //计数
while(head<tail) //队列不为空
{
int top=q[head++]; //队首出队
cnt++;
in[top]--; //输出点的入度降为-1
for(i=1; i<=n; i++) //删除top的后继
{
if(mp[top][i])
{
in[i]--;
if(!in[i]) //判断入度是否为零
{
q[tail++]=i; //入度为零的点入队
}
}
}
}
if(cnt==n)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
vector实现:
#include <iostream>
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
const int N = 11;
using namespace std;
vector<int>mp[N];
int in[N];
void Toposort(int n)
{
vector<int> zero; //入度为0的点
vector<int> ans; //排序结果
int i;
for(i=1;i<=n;i++) //找到入度为零的点
{
if(!in[i]) //入度为零的点入队
zero.push_back(i);
}
while(!zero.empty()) //队列不为空
{
int pos=zero.back();
zero.pop_back();
ans.push_back(pos);
int len=mp[pos].size();
for(i=0;i<len;i++)
{
int v=mp[pos][i];
in[v]--; //输出点的入度降1
if(!in[v]) //判断入度是否为零
zero.push_back(v); //入度为零的点入队
}
}
int len_ans=ans.size();
if(len_ans!=n)
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
// for(int i=0;i<ans.size();i++) //实现输出
// {
// cout<<ans[i]<<endl;
// }
}
int main()
{
int n,m;
while(cin>>n>>m)
{
memset(mp,0,sizeof(mp));
memset(in,0,sizeof(in));
while(m--)
{
int a,b;
cin>>a>>b;
mp[a].push_back(b);
in[b]++;
}
Toposort(n);
}
return 0;
}
stl队列
#include <iostream>
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
const int N = 11;
using namespace std;
int mp[N][N];
int in[N];
void Toposort(int n)
{
queue<int>q;
int i;
for(i=1; i<=n; i++)
{
if(!in[i])
q.push(i);
}
int cnt=0;
while(!q.empty())
{
int top=q.front();
q.pop();
cnt++;
in[top]--;
for(i=1; i<=n; i++)
{
if(mp[top][i])
{
in[i]--;
if(!in[i])
{
q.push(i);
}
}
}
}
if(cnt==n)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
int main()
{
int n,m;
while(cin>>n>>m)
{
memset(mp,0,sizeof(mp));
memset(in,0,sizeof(in));
while(m--)
{
int a,b;
cin>>a>>b;
mp[a][b]=1;
in[b]++;
}
Toposort(n);
}
return 0;
}
拓扑排序讲解:
[传送门](https://docs.qq.com/doc/DTmRnbHFYR3RGVkRx)