UVALive 4431 Fruit Weights --floyd,差分約束?

題意: 給出一些關係用aX <= bY表示, 最後查詢aX 和 bY的關係,是>=,==,<=,仍是不能肯定,仍是出現了矛盾。ios

解法:對每個關係其實均可以建一條X->Y的邊,邊權爲b/a,表示X <= b/a*Y,輸入完後,跑一遍floyd,對每一對點A,B跑出A<=xB的x的最小值。ide

由於若是真的存b/a的話,可能會損失很大的精度,可是好像這樣也能過。爲了更加保險,咱們能夠取個對數,log(b/a) = log(b)-log(a),那麼乘法就變成了加法,更好計算,也更加準確。spa

最後就是判斷了,設最後查詢的是k1,k2兩個點,比率爲ka,kbcode

1.==: 若是mp[k1][k2] == -mp[k2][k1], 便是倒數關係(對數是負數關係),且mp[k1][k2] = log(kb/ka),那麼就相等。blog

2.<=: 若是mp[k1][k2] <= log(kb/ka), 如今k1已經小於等於mp[k1][k2]了,那麼確定是小於等於log(kb/ka)的。ci

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

4.INCONSISTENT: 若是某個mp[i][i]爲負,說明有矛盾。it

5.其餘狀況io

代碼:event

#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
相關文章
相關標籤/搜索