题意:

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
*/