题目大意
给出n个变量,m个不等关系。
不等式之间具有传递性,通过传递性来判断这m个不等关系是不是可以确定两两变量之间的唯一大小关系
解法
利用Floyd算法来传递关系,利用二分法来确定最少需要不等式数量
如果所有不等关系可以直接确定,且没有矛盾,那么需要找到能唯一确定关系的最少不等式数量
如果所有不等关系不能确定,且没有矛盾,直接输出“Sorted sequence cannot be determined.”
其他情况则需要输出最少能确定矛盾或者推倒出不等关系的不等式数量
代码如下(直接按照思路直译的,没有加任何优化)
#include <bits/stdc++.h>
using namespace std;
int a[100010], b[100010];
int n, m;
int mp[30][30];
char ans[110];
void floyd(int pre)
{
memset(mp, 0x0, sizeof(mp));
for (int i = 1; i <= pre; i++)
{
mp[a[i]][b[i]] = 1;
}
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
mp[i][j] |= (mp[i][k] & mp[k][j]);
}
int check()
{
int flag = false;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (i == j)
continue;
else if (mp[i][j] && mp[j][i]) //关系矛盾
return -1;
else if (!(mp[i][j] || mp[j][i])) //没有找到关系
flag = true;
if (flag)
return 0;
return 1;
}
void get_string()
{
for (int i = 1; i <= n; i++)
{
int cnt = 0;
for (int j = 1; j <= n; j++)
if (mp[j][i])
cnt++;
ans[cnt + 1] = 'A' + i - 1;
}
ans[n + 1] = '\0';
}
int main()
{
while (true)
{
scanf("%d%d", &n, &m);
if (n == 0 || m == 0)
break;
char s[10];
for (int i = 1; i <= m; i++)
{
scanf("%s", s + 1);
int A, B;
A = s[1] - 'A' + 1;
B = s[3] - 'A' + 1;
if (s[2] == '<')
a[i] = A, b[i] = B;
else
a[i] = B, b[i] = A;
}
int l = 1, r = m;
floyd(m);
if (check() == -1) //直接矛盾
{
while (l != r)
{
int mid = (l + r) >> 1;
floyd(mid);
if (check() == 0)
l = mid + 1;
else
r = mid;
}
floyd(r);
if (check() == -1)
printf("Inconsistency found after %d relations.\n", r);
else
{
get_string();
printf("Sorted sequence determined after %d relations: %s.\n", r, ans + 1);
}
}
else if (check() == 0) //不能确定
{
printf("Sorted sequence cannot be determined.\n");
}
else //可以减少
{
while (l != r)
{
int mid = (l + r) >> 1;
floyd(mid);
if (check() == 0)
l = mid + 1;
else
r = mid;
}
floyd(r);
get_string();
printf("Sorted sequence determined after %d relations: %s.\n", r, ans + 1);
}
}
}