• [APIO2017]商旅


    link

    这题卡我精度,调了一晚上才调对,因为没有想到图还可以不连通

    其实可以预处理出好多东西,距离($dis(u,v)$),买卖物品(从$u$到$v$买卖物品的最大利润,例($max{S_{u,i}-B_{v,i}}$),然后其实可以发现就是一个十分普通普遍的分数规划式子,就每次二分$k$,然后建边,$spfa$判正环就行

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<climits>
    #include<queue>
    #define int long long
    using namespace std;
    inline int read(){
        int f=1,ans=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int MAXN=1001;
    int n,m,k;
    int dis[MAXN][MAXN],b[MAXN][MAXN],s[MAXN][MAXN],st[MAXN][MAXN],l,r,maxn,D[MAXN][MAXN],num[MAXN],Dis[MAXN],vis[MAXN];
    queue<int> que;
    bool check(int P){
        while(!que.empty()) que.pop();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++) D[i][j]=st[i][j]-dis[i][j]*P;
        memset(Dis,0,sizeof(Dis));
        memset(num,0,sizeof(num));
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++) num[i]=vis[i]=1,que.push(i);
        while(!que.empty()){
            int xx=que.front();que.pop();vis[xx]=0;
            for(int i=1;i<=n;i++){
                int d=D[xx][i];
                if(dis[xx][i]>INT_MAX) continue;
                if(Dis[xx]+d>=Dis[i]){
                    Dis[i]=d+Dis[xx];
                    num[i]=num[xx]+1;
                    if(num[i]>n+10) return 1;
                    if(!vis[i]){
                        vis[i]=1;
                        que.push(i);
                    }
                    
                }
            }
        }return 0;
    }
    signed main(){
        memset(dis,127/3,sizeof(dis));
        n=read(),m=read(),k=read();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=k;j++) b[i][j]=read(),s[i][j]=read();
        for(int i=1;i<=k;i++){
            for(int x=1;x<=n;x++)
               for(int y=1;y<=n;y++)
                if(b[x][i]!=-1&&s[y][i]!=-1) {
                    st[x][y]=max(st[x][y],s[y][i]-b[x][i]),r=max(r,st[x][y]);
                }
        }
        for(int i=1;i<=m;i++){
            int u=read(),v=read(),w=read();
            dis[u][v]=min(dis[u][v],w);
        }
        for(int ss=1;ss<=n;ss++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    dis[i][j]=min(dis[i][j],dis[i][ss]+dis[ss][j]);
        while(l<=r){
            int mid=l+r>>1;
            if(check(mid)) maxn=max(maxn,mid),l=mid+1;
            else r=mid-1;
        }
        printf("%lld
    ",maxn);
    }
    View Code
  • 相关阅读:
    哥德尔不完备定理
    关于欧拉公式证明的一个延拓
    关于贝叶斯定理的一个延拓
    贝克莱悖论
    自然数的公理化理论体系定义的新方法
    关于Spring中的<context:annotation-config/>配置
    <mvc:default-servlet-handler/>的作用
    web.xml context-param配置
    Spring JDBC框架操作mysql数据库
    Spring + JDBC example
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/10061314.html
Copyright © 2020-2023  润新知