P1347 排序 · znzryb
## 思路讲解
图论建模,拓扑排序。
拓扑排序的代码(使用BFS kahn‘s算法),通过判断q的大小可以知道其是不是严格的(该题目要求严格的顺序)。
```cpp
ll trop(const vector<ll> &a,ll siz){
vector<ll> op=a;
Ans.clear();
queue<ll> q;
ll ret=3; // 3成功 2不能确定 1冲突
FOR(i,'A','Z'){
if(vis[i] && op[i]==0) q.push(i),Ans.pb(i);
}
if(SZ(q)>1) ret=2;
while(!q.empty()){
if(SZ(q)>1) ret=2;
ll node=q.front();q.pop();
ll cnt=0;
FOR(i,0,SZ(g[node])-1){
ll lnode=g[node][i];
op[lnode]-=1;
if(op[lnode]==0){
q.push(lnode);
Ans.pb(lnode);
}
}
}
if(SZ(Ans)==siz){
if(SZ(Ans)<N){ // 还没完全确定
return 2;
}else{
return ret;
}
}else{ // 说明有环
return 1;
}
}
```
## AC代码
[https://www.luogu.com.cn/record/220236107](https://www.luogu.com.cn/record/220236107)
::: 源代码
```cpp
// Problem: P1347 排序
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1347
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
#define all(vec) vec.begin(),vec.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define fi first
#define se second
#define pb push_back
#define SZ(a) ((int) a.size())
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define ROF(i, a, b) for (int i = (a); i >= (b); --i)
#define debug(var) cerr << #var <<":"<<var<<"\n";
#define lson(var) (var<<1)
#define rson(var) ((var<<1)+1)
using namespace std;
typedef long long ll;typedef unsigned long long ull;
typedef double DB;typedef long double LD;
typedef __int128 i128;typedef pair<DB,DB> pdd;typedef pair<ll,bool> plb;
typedef pair<ll,ll> pll;
typedef array<ll,3> arr3;typedef array<ll,2> arr2;
constexpr ll MAXN=static_cast<ll>(3e2)+10,INF=static_cast<ll>(1e9)+9; // 1e18+9也是素数
constexpr ll mod=static_cast<ll>(1e9)+7;
constexpr double eps=1e-8;
ll N,M,Q,X,K,lT,A[MAXN];
vector<ll> g[MAXN]; // 记得要清空
bitset<MAXN> vis;
/*
*/
vector<ll> Ans;
inline void init(){
}
ll trop(const vector<ll> &a,ll siz){
vector<ll> op=a;
Ans.clear();
queue<ll> q;
ll ret=3; // 3成功 2不能确定 1冲突
FOR(i,'A','Z'){
if(vis[i] && op[i]==0) q.push(i),Ans.pb(i);
}
if(SZ(q)>1) ret=2;
while(!q.empty()){
if(SZ(q)>1) ret=2;
ll node=q.front();q.pop();
ll cnt=0;
FOR(i,0,SZ(g[node])-1){
ll lnode=g[node][i];
op[lnode]-=1;
if(op[lnode]==0){
q.push(lnode);
Ans.pb(lnode);
}
}
}
if(SZ(Ans)==siz){
if(SZ(Ans)<N){ // 还没完全确定
return 2;
}else{
return ret;
}
}else{ // 说明有环
return 1;
}
}
inline void solve(){
cin>>N>>M;
init();
// Inconsistency found after 2 relations.
// Sorted sequence determined after 4 relations: ABCD.
vector<ll> inde(300,0);
set<char> occ;
FOR(_,1,M){
string s;
cin>>s;
g[s[0]].pb(s[2]);
vis[s[0]]=true,vis[s[2]]=true;
occ.insert(s[0]),occ.insert(s[2]);
inde[s[2]]+=1;
ll ret=trop(inde,SZ(occ));
if(ret==1){
cout<<"Inconsistency found after "<<_<<" relations.\n";
return;
}else if(ret==3){
cout<<"Sorted sequence determined after "<<_<<" relations: ";
FOR(i,0,SZ(Ans)-1){
cout<<char(Ans[i]);
}
cout<<".\n";
return;
}
}
cout<<"Sorted sequence cannot be determined.\n";
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
// cin>>lT;
// while(lT--){
// solve();
// }
solve();
return 0;
}
/*
AC
https://www.luogu.com.cn/record/220236107
*/
```
:::
## 心路历程(WA,TLE,MLE……)