1. 程式人生 > >Gym 101655B Bones’s Battery floyed+二分

Gym 101655B Bones’s Battery floyed+二分

先跑一遍floyed,求出兩兩點對之間的最小距離。然後這個最小距離就相當於一個最新的地圖了,新地圖裡,小於當前二分列舉值,就充1次電,大於這個值,就衝無窮大次電,起點終點相等,就充0次電。再跑一次floyed,看看當前二分列舉的容量符不符合條件。

#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#include<cmath>
using namespace std;

const long long inf = 0x3f3f3f3f3f3f3f3f3f3f3f;

long long a[110][110],mapp[110][110];
int t,n,k,m;

int main()
{
    scanf("%d",&t);
    while (t--)
    {
        scanf("%d%d%d",&n,&k,&m);
        memset(mapp,inf,sizeof(mapp));
        for (int i=1; i<=m; i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            mapp[a][b]=mapp[b][a]=c;
        }
        for (int k=0; k<n; k++)
        {
            for (int i=0; i<n; i++)
            {
                for (int j=0; j<n; j++)
                {
                    mapp[i][j]=min(mapp[i][j],mapp[i][k]+mapp[k][j]);
                }
            }
        }
        long long l=1; long long r=inf; long long mid; long long ans;
        while (l<=r)
        {
            mid=l+r>>1;
            for (int i=0; i<n; i++)
            {
                for (int j=0; j<n; j++)
                {
                    if (i==j) a[i][j]=0;
                    else if (mapp[i][j]<=mid) a[i][j]=1;
                    else a[i][j]=inf;
                }
            }
            for (int k=0; k<n; k++)
            {
                for (int i=0; i<n; i++)
                {
                    for (int j=0; j<n; j++)
                    {
                        a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
                    }
                }
            }
            bool flag=true;
            for (int i=0; i<n; i++)
            {
                for (int j=0; j<n; j++)
                {
                    if (a[i][j]>k)
                    {
                        flag=false;
                        break;
                    }
                }
                if (!flag) break;
            }
            if (flag)
            {
                r=mid-1; ans=mid;
            }
            else l=mid+1;
        }
        cout<<ans<<endl;
    }
    return 0;
}