Gym 101655B Bones’s Battery floyed+二分
阿新 • • 發佈:2019-02-09
先跑一遍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; }