• UVALive 4431 Fruit Weights --floyd,差分约束?


    题意: 给出一些关系用aX <= bY表示, 最后查询aX 和 bY的关系,是>=,==,<=,还是不能确定,还是出现了矛盾。

    解法:对每一个关系其实都可以建一条X->Y的边,边权为b/a,表示X <= b/a*Y,输入完后,跑一遍floyd,对每一对点A,B跑出A<=xB的x的最小值。

    因为如果真的存b/a的话,可能会损失很大的精度,但是好像这样也能过。为了更加保险,我们可以取个对数,log(b/a) = log(b)-log(a),那么乘法就变成了加法,更好计算,也更加准确。

    最后就是判断了,设最后查询的是k1,k2两个点,比率为ka,kb

    1.==: 如果mp[k1][k2] == -mp[k2][k1], 即是倒数关系(对数是负数关系),且mp[k1][k2] = log(kb/ka),那么就相等。

    2.<=: 如果mp[k1][k2] <= log(kb/ka), 现在k1已经小于等于mp[k1][k2]了,那么肯定是小于等于log(kb/ka)的。

    3.>=: -mp[k2][k1] >= log(kb/ka) 

    4.INCONSISTENT: 如果某个mp[i][i]为负,说明有矛盾。

    5.其他情况

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <string>
    #include <map>
    #define Mod 1000000007
    #define eps 1e-8
    using namespace std;
    
    double mp[205][205];
    map<string,int> ms;
    
    int sgn(double x) {
        if(x > eps) return 1;
        if(x < -eps) return -1;
        return 0;
    }
    
    int main()
    {
        int n,i,j,a,b,tot,u,v,k;
        string S;
        while(scanf("%d",&n)!=EOF && n)
        {
            tot = 0;
            ms.clear();
            for(i=1;i<=2*n;i++) {
                for(j=1;j<=2*n;j++)
                    mp[i][j] = Mod;
                mp[i][i] = 0.0;
            }
            for(i=1;i<=n;i++) {
                scanf("%d",&a);
                cin>>S;
                if(!ms[S]) ms[S] = ++tot;
                u = ms[S];
                scanf("%d",&b);
                cin>>S;
                if(!ms[S]) ms[S] = ++tot;
                v = ms[S];
                mp[u][v] = min(mp[u][v],log((double)b/(double)a));
            }
            for(k=1;k<=tot;k++) {
                for(i=1;i<=tot;i++) {
                    for(j=1;j<=tot;j++)
                        mp[i][j] = min(mp[i][j],mp[i][k]+mp[k][j]);
                }
            }
            string S1,S2;
            scanf("%d",&a);
            cin>>S1;
            int k1 = ms[S1];
            scanf("%d",&b);
            cin>>S2;
            int k2 = ms[S2];
            double rate = log((double)b/(double)a);
            if(ms[S1] == 0 || ms[S2] == 0) { puts("UNAVAILABLE"); continue; }
            for(i=1;i<=tot;i++) if(sgn(mp[i][i]) < 0) { puts("INCONSISTENT"); break; }
            if(i != tot+1) continue;
            if(sgn(mp[k1][k2]+mp[k2][k1]) == 0 && sgn(mp[k1][k2]-rate) == 0) puts("==");
            else if(sgn(mp[k1][k2]-rate) <= 0) puts("<=");
            else if(sgn(-mp[k2][k1]-rate) >= 0) puts(">=");
            else puts("UNAVAILABLE");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    滚轮事件的防冒泡、阻止默认行为的代码(效果是:只让当前div滚动,连当前文档都不滚动的效果)
    js原生封装getClassName()方法-ie不支持getElementsByClassName,所以要自己实现获取类名为className的所有元素
    使用 RequireJS 优化 Web 应用前端
    javascript的页面加载及性能优化(兼容IE7)
    JavaScript中的this陷阱的最全收集--没有之一
    mysql 配置MHA
    mysql 在linux下的完整安装过程
    vue 开发系列(八) 动态表单开发
    vue 开发系列(七) 路由配置
    vue 开发系列(六) 企业微信整合
  • 原文地址:https://www.cnblogs.com/whatbeg/p/4234921.html
Copyright © 2020-2023  润新知