P1347 排序
链接:https://www.luogu.com.cn/problem/P1347
题目:
由于数据量很小,所以可以在线处理数据。
首先判断有没有环(这里不一定可以根据拓扑排序写出来,因为有的环可以只有部分节点,所以必须遍历所有节点的路径,判断有没有环);
然后查看入度为0的点,如果没有环而且入度为0的点多于1个,那么就是无法确定,如果没有点那么显然就是一个环,上一步可以判断出来。
如果只有一个,那么判断能不能排序,就是拓扑排序能不能走到底。
代码:
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
typedef long long ll;
using namespace std;
const int N = 30; int n;
int rd[N]; vector<int>G[N];
int rd_tem[N];bool vis[N];bool jd = true;
void dfsk(int id);
bool hasroll(int n)
{
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++)
{
dfsk(i);//dfsk,true::有环
}
return jd;
}
void dfsk(int id)
{
vis[id] = true;
if (jd)return;
for (int u : G[id])
{
if (vis[u])
{
jd = true; return;
}
if (jd)return;
dfsk(u);
}
if (jd)return;
vis[id] = false;
}
int dfs(int id, queue<int>*q)
{
if (q->size() == n)return 0;
int knum = 0; int kid = 0;
for (int i = 0; i < G[id].size(); i++)
{
int v = G[id][i];
rd_tem[v]--;
if (!rd_tem[v]) { knum++; kid = v; }
}
if (knum > 1)return 3;
if (knum == 0)return 1;
q->push(kid);
return dfs(kid, q);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int m;
cin >> n >> m;
for(int i=1;i<=m;i++)
{
string s; cin >> s;
if(s[0] == s[2])
{
cout << "Inconsistency found after " << i << " relations.";
return 0;
}
G[s[0] - 'A'+1].push_back(s[2] - 'A'+1);
rd[s[2] - 'A'+1]++;
int numofzero = 0; int zeroid = 0;
for (int i = 1; i <= n; i++)
if (!rd[i])
{
numofzero++;
zeroid = i;
}
if (!numofzero)
{
cout << "Inconsistency found after " << i << " relations.";
return 0;
}
jd = false;
if(hasroll(n))
{
cout << "Inconsistency found after " << i << " relations.";
return 0;
}
if (numofzero > 1 )
continue;
//环 or 线
for (int i = 1; i <= n; i++)rd_tem[i] = rd[i];
queue<int>ans;
ans.push(zeroid);
int jd = dfs(zeroid,&ans);
if (jd == 1)//环,直接跳
{
cout << "Inconsistency found after " << i << " relations.";
return 0;
}
else if (jd == 0)//线,肯定行
{
cout << "Sorted sequence determined after " << i << " relations: ";
while (!ans.empty()) { char s='A' + (ans.front() - 1); cout << s; ans.pop(); }
cout << '.';
return 0;
}
}
cout << "Sorted sequence cannot be determined.";
return 0;
}