题意:
n个点,m个边,两两之间可以到达
我们要运送货物,如果量是x,运送第一天是x,第二天是x
,第n天是x
,运送几天取决于起点和终点的长度,长度=运送天数,问现在预算是budget,从s到t最多能运多少货物?
题解:
脑残了。。n<100,我们肯定要先求出任意两点的最短距离,还用什么spfa,什么地杰斯特拉,直接floyed不香吗
预算是budget,货物是x,天数(路径长)为len
当budget>x^1+x^2+...x^len=x*(1-x)/(1-x)
现在知道budget,知道len,求x的最大情况,那直接二分不就OK了
emmm。。。好简单,比赛时为什么没做出来。。。
代码:
/*
3 2
1 2
2 3
2
1 3 5
2 3 2
*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=200;
ll dis[maxn][maxn];
ll budget,len;
bool check(int x)
{
ll sum=0,r=1;
for(int i=1;i<=len;i++)
{
r*=x;
sum+=r;
if(sum>budget)return 0;
}
// sum=pow(x,len);
if(sum<=budget)return 1;
else return 0;
}
int main(){
int n,m;
cin>>n>>m;
memset(dis, 0x3f3f3f3f, sizeof(dis));
for(int i=1;i<=m;i++)
{
int x,y;
cin>>x>>y;
dis[x][y]=1;
dis[y][x]=1;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
for(int k=1;k<=n;k++)
{
if(dis[i][j]>dis[i][k]+dis[k][j])
dis[i][j]=dis[i][k]+dis[k][j];
dis[j][i]=dis[i][j];
}
}
}
int t;
cin>>t;
while(t--)
{
int u,v;
cin>>u>>v>>budget;
len=dis[u][v];
ll l=0,r=budget;
while(l<r)
{
ll mid=(l+r+1)>>1;
if(check(mid))l=mid;
else r=mid-1;
}
cout<<l<<endl;
}
}
/*
5
1 2 1 2 3
*/

京公网安备 11010502036488号