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)(最长路径):
#include <cstdio>
#include <cstring>
#include <map>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL; const int MAXN = ;
const double EPS = 1e-; map<string, int> mp;
string a, b;
int m, n; double x, y;
int aid, bid;
double mat[MAXN][MAXN]; inline int sgn(double x) {
return (x > EPS) - (x < -EPS);
} bool floyd() {
for(int k = ; k <= n; ++k)
for(int i = ; i <= n; ++i) if(mat[i][k] > )
for(int j = ; j <= n; ++j) if(mat[k][j] > )
if(mat[i][k] * mat[k][j] > mat[i][j]) mat[i][j] = mat[i][k] * mat[k][j];
/*
for(int k = 1; k <= n; ++k)
for(int i = 1; i <= n; ++i) if(mat[i][k] > 0)
for(int j = 1; j <= n; ++j) if(mat[k][j] > 0)
if(mat[i][j] > 0 && sgn(mat[i][k] * mat[k][j] - mat[i][j]) == 1) return false;*/
for(int i = ; i <= n; ++i)
for(int j = i + ; j <= n; ++j) {
if(mat[i][j] < || mat[j][i] < ) continue;
if(mat[i][j] * mat[j][i] > ) return false;
}
return true;
} int main() {
ios::sync_with_stdio(false);
while(cin>>m) {
if(m == ) break;
n = ;
mp.clear();
for(int i = ; i < MAXN; ++i) {
for(int j = ; j < MAXN; ++j) mat[i][j] = -;
mat[i][i] = ;
}
for(int i = ; i < m; ++i) {
cin>>x>>a>>y>>b;
if(mp.find(a) != mp.end()) aid = mp[a];
else mp[a] = aid = ++n;
if(mp.find(b) != mp.end()) bid = mp[b];
else mp[b] = bid = ++n;
//if(mat[aid][bid] < double(x, y)) mat[aid][bid] = double(x, y);
if(mat[bid][aid] < x / y) mat[bid][aid] = x / y;
}
cin>>x>>a>>y>>b;
if(!floyd()) {
puts("INCONSISTENT");
continue;
}
if(mp.find(a) == mp.end() || mp.find(b) == mp.end()) {
puts("UNAVAILABLE");
continue;
}
aid = mp[a];
bid = mp[b];
if(sgn(mat[aid][bid] - y / x) == && sgn(mat[bid][aid] - x / y) == ) {
puts("==");
continue;
}
if(mat[bid][aid] > && sgn(mat[bid][aid] - x / y) >= ) {
puts("<=");
continue;
}
if(mat[aid][bid] > && sgn(mat[aid][bid] - y / x) >= ) {
puts(">=");
continue;
}
puts("UNAVAILABLE");
}
}
代码(125MS)(最短路径):
#include <cstdio>
#include <cstring>
#include <map>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL; const int MAXN = ;
const double EPS = 1e-; map<string, int> mp;
string a, b;
int m, n; double x, y;
int aid, bid;
double mat[MAXN][MAXN]; inline int sgn(double x) {
return (x > EPS) - (x < -EPS);
} bool floyd() {
for(int k = ; k <= n; ++k)
for(int i = ; i <= n; ++i) if(mat[i][k] > )
for(int j = ; j <= n; ++j) if(mat[k][j] > )
if(mat[i][j] < || mat[i][k] * mat[k][j] < mat[i][j]) mat[i][j] = mat[i][k] * mat[k][j];
for(int i = ; i <= n; ++i)
for(int j = i + ; j <= n; ++j) {
if(mat[i][j] < || mat[j][i] < ) continue;
if(sgn(mat[i][j] * mat[j][i] - ) < ) return false;
}
return true;
} int main() {
ios::sync_with_stdio(false);
while(cin>>m) {
if(m == ) break;
n = ;
mp.clear();
for(int i = ; i < MAXN; ++i) {
for(int j = ; j < MAXN; ++j) mat[i][j] = -;
mat[i][i] = ;
}
for(int i = ; i < m; ++i) {
cin>>x>>a>>y>>b;
if(mp.find(a) != mp.end()) aid = mp[a];
else mp[a] = aid = ++n;
if(mp.find(b) != mp.end()) bid = mp[b];
else mp[b] = bid = ++n;
if(aid == bid) continue;
//if(mat[aid][bid] < double(x, y)) mat[aid][bid] = double(x, y);
if(mat[bid][aid] < || mat[bid][aid] > y / x) mat[bid][aid] = y / x;
}
cin>>x>>a>>y>>b;
if(!floyd()) {
puts("INCONSISTENT");
continue;
}
if(mp.find(a) == mp.end() || mp.find(b) == mp.end()) {
puts("UNAVAILABLE");
continue;
}
aid = mp[a];
bid = mp[b];
if(sgn(mat[aid][bid] - x / y) == && sgn(mat[bid][aid] - y / x) == ) {
puts("==");
continue;
}
if(mat[bid][aid] > && sgn(mat[bid][aid] - y / x) <= ) {
puts("<=");
continue;
}
if(mat[aid][bid] > && sgn(mat[aid][bid] - x / y) <= ) {
puts(">=");
continue;
}
puts("UNAVAILABLE");
}
}
POJ 3860 Fruit Weights(数学+最长路径 or 最短路径)的更多相关文章
- POJ 1797 Heavy Transportation(Dijkstra变形——最长路径最小权值)
题目链接: http://poj.org/problem?id=1797 Background Hugo Heavy is happy. After the breakdown of the Carg ...
- 【POJ 3162】 Walking Race (树形DP-求树上最长路径问题,+单调队列)
Walking Race Description flymouse's sister wc is very capable at sports and her favorite event is ...
- Going from u to v or from v to u? POJ - 2762(强连通 有向最长路径)
In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, an ...
- ubuntu 终端设置(颜色与长路径)
Linux给人最大的享受就是可以根据个人喜好去定制令自己舒服的系统配置,像终端颜色的设置就是一个典型的例子. 图1 系统默认状态下的终端显示 在没有经过自定义配置的终端下工作久了,难免容易疲劳 ...
- Codefroces Gym 100781A(树上最长路径)
http://codeforces.com/gym/100781/attachments 题意:有N个点,M条边,问对两两之间的树添加一条边之后,让整棵大树最远的点对之间的距离最近,问这个最近距离是多 ...
- poj 2533 Longest Ordered Subsequence 最长递增子序列
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4098562.html 题目链接:poj 2533 Longest Ordered Subse ...
- hdoj 2196 Computer【树的直径求所有的以任意节点为起点的一个最长路径】
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- AOE网上的关键路径(最长路径 + 打印路径)
题目描述 一个无环的有向图称为无环图(Directed Acyclic Graph),简称DAG图. AOE(Activity On Edge)网:顾名思义,用边表示活动的网,当然它也是DAG ...
- HDU 1069 Monkey and Banana / ZOJ 1093 Monkey and Banana (最长路径)
HDU 1069 Monkey and Banana / ZOJ 1093 Monkey and Banana (最长路径) Description A group of researchers ar ...
随机推荐
- 从 React 的组件更新谈 Immutable 的应用
在介绍 Immutable 如何在 React 中应用之前,先来谈谈 React 组件是如何更新的. React 是基于状态驱动的开发,可以将一个组件看成是一个有限状态机,组件要更新,必须更新状态. ...
- 网页后缀html、htm、shtml、shtm有什么区别?
每一个网页或者说是web页都有其固定的后缀名,不同的后缀名对应着不同的文件格式和不同的规则.协议.用法,最常见的web页的后缀名是.html和.htm,但这只是web页最基本的两种文件格式,今天我们来 ...
- spring boot 小案例
1. SpringBoot 1.1. 概要 在传统的SSM框架应用过程中,存在大量的配置文件,及相关的配置项,例如: 1. DispatcherServlet 2. CharacterEncoding ...
- Percona-Tookit工具包之pt-ioprofile
Preface As a matter of fact,disk IO is the most important factor which tremendously influenc ...
- Python基础——字典和有序字典
字典 说明: 在 Python 中, 字典 是一系列 键 — 值对 .每个键都与一个值相关联,你可以使用键来访问与之相关联的值.与键相关联的值可以是数字.字符串.列表乃至字典.事实上,可将任何 Pyt ...
- vue过渡动画效果
1 过渡基础 1.1 过渡的方式 Vue 在插入.更新或者移除 DOM 时,提供多种不同方式的应用过渡效果. 包括以下工具: 在 CSS 过渡和动画中自动应用 class 可以配合使用第三方 CSS ...
- symfony 安装使用(一)
Symfony安装教程网上已经存在很多了,但是这里还是要写一下: 1.symfony 安装有以下几种,对应不同的环境 1.1通过composer 命令安装 composer create-projec ...
- 商城项目:商品列表ajax加载,ajax加入购物车--五张表的联合查询
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ProductLists.a ...
- CRC校验8
什么是CRC校验? CRC即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定.循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并 ...
- 08 datetime与logging模块(进阶)
datetime与logging模块 阶段一:日期与时间 1.datetime 模块中 主要类: 类名 功能说明 date 日期对象,常用的属性有year, month, day time 时间对象h ...