POJ 3860 Fruit Weights(数学+最长路径 or 最短路径)

Description

Have you ever thought about comparing the weight of fruits? That’s what you should do in this problem! Given a series of fruit weight comparisons, you should anticipate the result of another comparison. In this problem, all fruits of the same kind are identical and have the same weights. Each fruit weight comparison is something like “a X ≤ b Y” in which a and b are positive integers, and X and Y are fruit names. Such a comparison means that the weight of a fruits of type X is less than or equal to the weight of b fruits of type Y.

Input

The input contains multiple test cases. Each test case starts with a line containing n, which is the number of given comparisons. Each of the next n lines gives a comparison in the form of “a X b Y” meaning that “a X ≤ b Y”. The last line of each test case contains the comparison query in the same form of “a X b Y” inquiring the comparison of “a X” and “b Y”.  
A case of n = 0 shows the end of input and should not be processed. All integers in the input (except the last n which is 0) are positive and are not greater than 100. Fruit names are case-sensitive strings of (lowercase and uppercase) letters with length no more than 50.

Output

For each test case, write one line with your result for that test case. Your result can be one of the followings (assume the comparison query was “a X b Y”):   “<=”: meaning you are sure that “a X ≤ b Y”.   “>=”: meaning you are sure that “a X ≥ b Y”.   “==”: meaning you are sure that “a X = b Y” (i.e. you have reached both of the above results).   “UNAVAILABLE”: meaning that you can say nothing for sure in comparing “a X” and “b Y” (i.e. you have reached none of the above results).   “INCONSISTENT”: meaning that there is an inconsistency in the given comparisons (i.e. you are sure that all the given comparisons for that test case cannot hold at the same time).

 

题目大意:给n条aX ≤ bY的不等式,其中X、Y是未知数的符号,a、b是常数。最后给出aX ? bY,要求判断 ? 是哪个符号。如果相等输出==,大于等于输出>=,小于等于输出<=,不能判断输出UNAVAILABLE,n条不等式不可能同时成立输出INCONSISTENT。

思路:首先X、Y是各种各样的字符串,所以先离散化,C++里面的map<string, int>是不错的选择。然后我们就要考虑,不同的不等式,该怎样才能联立起来。比如2a ≤ 3b,5b ≤ 7c,这样就会确定了一个关于a和c的不等式,然而我们须要表现在代码里面,不是很容易做到。

所以移向,2/3 a ≤ b, 5/7 b ≤ c,如果 c 到 b 连一条边,权值为 5/7; b 到 a 连一条边,权值为 2/3。那么,我们从 c 走到 a,就可以得到 (5/7 * 2/3) * a ≤ c。如果有假设提问是x * a ? y * c,那么对所有x/y ≤ (5/7 * 2/3),因为若p ≤ q,有pa ≤ qa ≤ qc。

然后对每一条边,取最大的权值。因为若有两条边pa ≤ pc,qa ≤ qc,且p ≤ q,那么我们只要保留qa ≤ qc,那么我们就可以推断出pa ≤ pc。

根据上述推论,我们用floyd来直接求出最长路径,mat[j][i]代表mat[j][i] * i ≤ j。n个不等式冲突,就说明存在mat[i][i] > 1,令mat[i][i] * i ≤ i无法成立,输出INCONSISTENT。对询问x * i ? y * j,若有y/x = mat[i][j]且x/y = mat[j][i],那么有x * i = y * j。若有y/x ≤ mat[i][j],则有x * i ≥ y * j。若 x/y ≤ mat[j][i],则有x * i ≤ y * j。若前面都不成立,则说明无法判断,输出UNAVAILABLE。

对于询问x * i ? y * j, i 或 j 前面都没有出现过的,好像是没有这种情况,别人没管这个也能AC。

PS:之前闲得无聊写了一个分数类结果RE了,大概是乘起来太大然后求约数的时候被零除跪了,好吧这不是重点。

PS2:最短路径的那个代码就是把原来的mat[j][i] * i ≤ j换成了i ≤ j * mat[j][i],思路差不多。

 

代码(125MS)(最长路径):

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <map>

 4 #include <string>

 5 #include <iostream>

 6 #include <algorithm>

 7 using namespace std;

 8 typedef long long LL;

 9 

10 const int MAXN = 220;

11 const double EPS = 1e-8;

12 

13 map<string, int> mp;

14 string a, b;

15 int m, n;

16 

17 double x, y;

18 int aid, bid;

19 double mat[MAXN][MAXN];

20 

21 inline int sgn(double x) {

22     return (x > EPS) - (x < -EPS);

23 }

24 

25 bool floyd() {

26     for(int k = 1; k <= n; ++k)

27         for(int i = 1; i <= n; ++i) if(mat[i][k] > 0)

28             for(int j = 1; j <= n; ++j) if(mat[k][j] > 0)

29                 if(mat[i][k] * mat[k][j] > mat[i][j]) mat[i][j] = mat[i][k] * mat[k][j];

30                 /*

31     for(int k = 1; k <= n; ++k)

32         for(int i = 1; i <= n; ++i) if(mat[i][k] > 0)

33             for(int j = 1; j <= n; ++j) if(mat[k][j] > 0)

34                 if(mat[i][j] > 0 && sgn(mat[i][k] * mat[k][j] - mat[i][j]) == 1) return false;*/

35     for(int i = 1; i <= n; ++i)

36         for(int j = i + 1; j <= n; ++j) {

37             if(mat[i][j] < 0 || mat[j][i] < 0) continue;

38             if(mat[i][j] * mat[j][i] > 1) return false;

39         }

40     return true;

41 }

42 

43 int main() {

44     ios::sync_with_stdio(false);

45     while(cin>>m) {

46         if(m == 0) break;

47         n = 0;

48         mp.clear();

49         for(int i = 1; i < MAXN; ++i) {

50             for(int j = 1; j < MAXN; ++j) mat[i][j] = -1;

51             mat[i][i] = 1;

52         }

53         for(int i = 0; i < m; ++i) {

54             cin>>x>>a>>y>>b;

55             if(mp.find(a) != mp.end()) aid = mp[a];

56             else mp[a] = aid = ++n;

57             if(mp.find(b) != mp.end()) bid = mp[b];

58             else mp[b] = bid = ++n;

59             //if(mat[aid][bid] < double(x, y)) mat[aid][bid] = double(x, y);

60             if(mat[bid][aid] < x / y) mat[bid][aid] = x / y;

61         }

62         cin>>x>>a>>y>>b;

63         if(!floyd()) {

64             puts("INCONSISTENT");

65             continue;

66         }

67         if(mp.find(a) == mp.end() || mp.find(b) == mp.end()) {

68             puts("UNAVAILABLE");

69             continue;

70         }

71         aid = mp[a];

72         bid = mp[b];

73         if(sgn(mat[aid][bid] - y / x) == 0  && sgn(mat[bid][aid] - x / y) == 0) {

74             puts("==");

75             continue;

76         }

77         if(mat[bid][aid] > 0 && sgn(mat[bid][aid] - x / y) >= 0) {

78             puts("<=");

79             continue;

80         }

81         if(mat[aid][bid] > 0 && sgn(mat[aid][bid] - y / x) >= 0) {

82             puts(">=");

83             continue;

84         }

85         puts("UNAVAILABLE");

86     }

87 }
View Code

代码(125MS)(最短路径):

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <map>

 4 #include <string>

 5 #include <iostream>

 6 #include <algorithm>

 7 using namespace std;

 8 typedef long long LL;

 9 

10 const int MAXN = 220;

11 const double EPS = 1e-8;

12 

13 map<string, int> mp;

14 string a, b;

15 int m, n;

16 

17 double x, y;

18 int aid, bid;

19 double mat[MAXN][MAXN];

20 

21 inline int sgn(double x) {

22     return (x > EPS) - (x < -EPS);

23 }

24 

25 bool floyd() {

26     for(int k = 1; k <= n; ++k)

27         for(int i = 1; i <= n; ++i) if(mat[i][k] > 0)

28             for(int j = 1; j <= n; ++j) if(mat[k][j] > 0)

29                 if(mat[i][j] < 0 || mat[i][k] * mat[k][j] < mat[i][j]) mat[i][j] = mat[i][k] * mat[k][j];

30     for(int i = 1; i <= n; ++i)

31         for(int j = i + 1; j <= n; ++j) {

32             if(mat[i][j] < 0 || mat[j][i] < 0) continue;

33             if(sgn(mat[i][j] * mat[j][i] - 1) < 0) return false;

34         }

35     return true;

36 }

37 

38 int main() {

39     ios::sync_with_stdio(false);

40     while(cin>>m) {

41         if(m == 0) break;

42         n = 0;

43         mp.clear();

44         for(int i = 1; i < MAXN; ++i) {

45             for(int j = 1; j < MAXN; ++j) mat[i][j] = -1;

46             mat[i][i] = 1;

47         }

48         for(int i = 0; i < m; ++i) {

49             cin>>x>>a>>y>>b;

50             if(mp.find(a) != mp.end()) aid = mp[a];

51             else mp[a] = aid = ++n;

52             if(mp.find(b) != mp.end()) bid = mp[b];

53             else mp[b] = bid = ++n;

54             if(aid == bid) continue;

55             //if(mat[aid][bid] < double(x, y)) mat[aid][bid] = double(x, y);

56             if(mat[bid][aid] < 0 || mat[bid][aid] > y / x) mat[bid][aid] = y / x;

57         }

58         cin>>x>>a>>y>>b;

59         if(!floyd()) {

60             puts("INCONSISTENT");

61             continue;

62         }

63         if(mp.find(a) == mp.end() || mp.find(b) == mp.end()) {

64             puts("UNAVAILABLE");

65             continue;

66         }

67         aid = mp[a];

68         bid = mp[b];

69         if(sgn(mat[aid][bid] - x / y) == 0  && sgn(mat[bid][aid] - y / x) == 0) {

70             puts("==");

71             continue;

72         }

73         if(mat[bid][aid] > 0 && sgn(mat[bid][aid] - y / x) <= 0) {

74             puts("<=");

75             continue;

76         }

77         if(mat[aid][bid] > 0 && sgn(mat[aid][bid] - x / y) <= 0) {

78             puts(">=");

79             continue;

80         }

81         puts("UNAVAILABLE");

82     }

83 }
View Code

 

你可能感兴趣的:(最短路径)