Sort AcWing
Description
Given n variables, m inequalities.
Inequality between transitive, that is, if A> B and B> C, then A> C.
It is determined whether inequality m contradictory.
If there is contradiction, the minimum value of t is determined, just before t satisfies inequality can be determined contradiction between inequality.
Without contradiction, it is determined whether the inequality m can determine the relationship between each of the variables.
If, then obtain the minimum value of t, t satisfy the inequality just before can determine the magnitude relationship between the variables of each pair.
Input
Test input comprising a plurality of sets of data.
Each test, the first line contains two integers n and m.
Subsequently m rows, each row containing an inequality, less than all of the inequality relationship.
When the input line 00, represents the input termination.
Output
A data output representing the results of each line.
The result may be one of the following three:
1, "Sorted sequence determined after t relations:. Yyy ... y", which refers to all yyy ... y variables in ascending order.
2, "Sorted sequence can not be determined.".
3, "Inconsistency found after t relations .".
Data Size
- 2 ≦ n- ≤ 26, the variable may only capital letters A ~ Z.
Sample Input
4 6 A<B A<C B<C C<D B<D A<B 3 2 A<B B<A 26 1 A<Z 0 0
Sample Output
Sorted sequence determined after 4 relations: ABCD. Inconsistency found after 2 relations. Sorted sequence cannot be determined.
answer:
- Floyd / topological sorting.
- This problem is obviously a transitive closure of the title, first i <j written as f (i, j) = 1. Flyod then passed under the closure. After two cycles pass enumeration i and j, if present, f (i, j) and F (j, i) are 1, a contradiction. When f (i, j) and f (j, i) is 0, indicating that can not be determined. The earliest position may be determined and then with diethyl points.
- Well but I tried to write a topology.
- First of all i <j, then even an edge of i to j. Clearly, then determine the relationship must be a chain. Then each added a set of relationships, do a topology. If there is a ring, a direct contradiction to return. In the internal topology function in each round if there is> 1 point appears in the queue, can not be determined explained. After the final finish topology, it can be determined and no explanation is contradictory, if it comes to a point and then all the points already, you can return.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#define N 105
using namespace std;
struct E {int next, to;} e[100005];
int n, m, num;
int h[N], in[N], t[N], seq[N];
bool vis[N], tag[N];
bool rel[N][N];
vector<int> a;
void add(int u, int v)
{
e[++num].next = h[u];
e[num].to = v;
h[u] = num;
}
int topsort()
{
queue<int> que;
int flag = 0, cnt = 0;
for(int i = 1; i <= 26; i++) t[i] = in[i];
for(int i = 0; i < a.size(); i++)
if(!in[a[i]]) que.push(a[i]);
while(que.size())
{
if(que.size() > 1) flag = 1;
int now = que.front(); que.pop();
seq[++cnt] = now;
for(int i = h[now]; i != 0; i = e[i].next)
{
in[e[i].to]--;
if(!in[e[i].to]) que.push(e[i].to);
}
}
for(int i = 1; i <= 26; i++) in[i] = t[i];
if(cnt != a.size()) return -1;
if(!flag && cnt == n) return 1;
else return 0;
}
void ini()
{
a.clear(), num = 0;
memset(h, 0, sizeof(h));
memset(vis, 0, sizeof(vis));
memset(in, 0, sizeof(in));
memset(rel, 0, sizeof(rel));
}
int main()
{
while(scanf("%d%d", &n, &m) == 2)
{
if(!n && !m) break;
ini();
for(int i = 1; i <= m; i++)
{
char c[6]; scanf("%s", c);
int u = c[0] - 'A' + 1, v = c[2] - 'A' + 1;
if(!rel[u][v])
{
rel[u][v] = 1;
if(!vis[u]) vis[u] = 1, a.push_back(u);
if(!vis[v]) vis[v] = 1, a.push_back(v);
add(u, v), in[v]++;
}
int ans = topsort();
if(ans == -1)
{
printf("Inconsistency found after %d relations.\n", i);
for(int j = i + 1; j <= m; j++) scanf("%s", c);
break;
}
else if(!ans && i == m) printf("Sorted sequence cannot be determined.\n");
else if(ans == 1)
{
printf("Sorted sequence determined after %d relations: ", i);
for(int j = 1; j <= n; j++) printf("%c", (char)(seq[j] - 1 + 'A'));
printf(".\n");
for(int j = i + 1; j <= m; j++) scanf("%s", c);
break;
}
}
}
return 0;
}