差分约束乘法改加减

洛谷P4926 [1007] 倍杀测量者

image

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
const double INF=1e18;
const double eps=1e-7;
struct node{
    int v;
    double k;
    int tp;
};
vector<node> edges[N];
int n,s,t,cnt[N];
bool vis[N];
double dp[N];
bool spfa(double T){
    for(int i=0;i<=n+1;i++){
        dp[i]=-INF;
        vis[i]=false;
        cnt[i]=0;
    }
    queue<int> q;
    q.push(n+1);
    dp[n+1]=0;
    vis[n+1]=true;
    while(q.size()){
        int u=q.front();
        q.pop();
        vis[u]=false;
        for(auto &[v,k,tp]:edges[u]){
            double w=k;
            if(tp==1){
                w=log2(w-T);
            }
            else if(tp==2){
                w=-log2(w+T);
            }
            if(dp[v]<dp[u]+w){
                dp[v]=dp[u]+w;
                cnt[v]=cnt[u]+1;
                if(!vis[v]){
                    vis[v]=true;
                    q.push(v);
                }
                if(cnt[v]>=n+2)
                    return true;
            }
        }
    }
    return false;
}

int main(){
    // cin.tie(nullptr)->sync_with_stdio(false);
    cin>>n>>s>>t;
    double l=0,r=10;
    for(int i=0;i<=n;i++){
        edges[n+1].push_back({i,0,3});
    }
    for(int i=1;i<=s;i++){
        int op,a,b,k;
        cin>>op>>a>>b>>k;
        edges[b].push_back({a,(double)k,op});
        if(op==1)
            r=fmin(r,k-eps);
    }
    for(int i=1;i<=t;i++){
        int c,x;
        cin>>c>>x;
        edges[c].push_back({0,-log2(x),3});
        edges[0].push_back({c,log2(x),3});
    }
    if(!spfa(0)){
        cout<<-1<<endl;
        return 0;
    }
    while(r-l>eps){
        double mid=(l+r)/2;
        if(spfa(mid)){
            l=mid;
        }
        else{
            r=mid;
        }
    }
    printf("%.6lf\n",l);
    return 0;
}
posted @ 2025-10-08 16:28  xdhking  阅读(7)  评论(0)    收藏  举报