POJ 3860 Fruit Weights(数学+最长路径 or 最短路径)
Description
Input
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
题目大意:给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)(最长路径):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
代码(125MS)(最短路径):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }