P3778 [APIO2017]商旅 Floyd+分數規劃
阿新 • • 發佈:2020-09-19
題意:
能力有限,沒有一句話題意,自己看吧
分析:
求盈利效率最大,要麼貪心,要麼分數規劃,貪心不太現實,那就只能考慮分數規劃了。所以我們要處理處分數規劃所需要的價值和體積,由於這道題的\(n\)極小,只有100,完全可以floyd處理
tip:需要注意的就是,分數規劃時會給\(ans\)乘上體積,若體積初始化為極大值會爆精度,所以體積初始化的時候手動賦值為一個較大的就可以了
程式碼:
#include<bits/stdc++.h> using namespace std; namespace zzc { const int maxm = 1e4+5; const int inf = 1e9+5; long long n,m,t; long long b[105][1005],s[105][1005],val[105][105],dis[105][105],f[105][105]; bool check(long long x) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i==j) f[i][j]=-0x3f3f3f; else f[i][j]=val[i][j]-x*dis[i][j]; } } for(int k=1;k<=n;k++) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { f[i][j]=max(f[i][k]+f[k][j],f[i][j]); } } } long long tmp=-0x3f3f3f3f; for(int i=1;i<=n;i++) { tmp=max(tmp,f[i][i]); } return tmp>=0; } long long getans() { long long l=0,r=1e9,mid,res; while(l<=r) { mid=(l+r)>>1; if(check(mid)) { res=mid; l=mid+1; } else r=mid-1; } return res; } void work() { scanf("%lld%lld%lld",&n,&m,&t); for(int i=1;i<=n;i++) { for(int j=1;j<=t;j++) { scanf("%lld%lld",&b[i][j],&s[i][j]); if(b[i][j]==-1) b[i][j]=inf; if(s[i][j]==-1) s[i][j]=-inf; } } for(int k=1;k<=t;k++) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { val[i][j]=max(val[i][j],s[j][k]-b[i][k]); } } } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { dis[i][j]=inf; } } for(int i=1;i<=m;i++) { long long a,b,c; scanf("%lld%lld%lld",&a,&b,&c); dis[a][b]=c; } for(int k=1;k<=n;k++) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(dis[i][k]==inf||dis[k][j]==inf) continue; dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); } } } printf("%lld\n",getans()); } } int main() { zzc::work(); return 0; }