K
欢欢一直在研究狂热的编程问题。然而,今天他决定让自己休息一下,去一个美丽的国家旅行。因此,出现了另一个问题。
全国共有n个城市。有m 条双向道路,每条道路都直接连接两个不同的城市。由于该国拥有稳固的交通系统,因此每两个城市之间总会有一条路径连接。
欢欢到了S市,想把尽可能多的物品运到T市。每天他都会走过一条路。每经过一条路,都要付出一定的代价。根据政策,费用取决于您携带的物品数量和您进入该国的天数。更准确地说,每条道路的费用是k d,其中k 是黄欢要携带的物品数量,d 是他入境的天数。
例如,黄环到达ar市1 ,瞄准市3 。他选择的路径是1->2->3 携带2 个 物品。那么路1->2的费用 将是2 1 和路2->3的费用 将是2 2 . 所以总费用是2 1 +2 2 =6
现在,您的任务是帮助他决定他可以携带的最大物品数量,因为他的预算有限。
不过,欢欢准备在未来多次出差。将为您提供完全Q 查询。
输入描述:
第一行包含两个整数 n,m (1≤n≤100, m≤(n(n+1)/2)),其中 n 是城市数量,m 是道路数量。(保证每两个城市相连,没有两条道路直接连接同一两个城市。)
然后,将m行跟随,第i个 线包含两个整数ui,vi (1≤ui,vi≤N,ui≠vi),表示第i个 路连接城市ui 和vi。
接下来的几行包含一个整数 q(1≤Q≤10 5 ),表示查询的次数。
然后是Q行,每行包含3个整数S、T、B(1≤S,T≤n,0≤B≤1e9),分别表示到达的城市、目标城市和预算。
输出描述:
对于每个查询,打印一个整数作为欢欢从城市 S 到 T 可以携带的最大项目。
示例1
输入
3 2
1 2
2 3
3
1 2 5
1 3 5
2 3 2
输出
5
1
2
思路
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF=1e9;
const int N=110;
int dis[N][N];
int main()
{
int n,m;int x,y;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
dis[i][j]=0x3f3f3f3f;
}
for(int i=0;i<m;i++)
{
cin>>x>>y;
dis[x][y]=dis[y][x]=1;//表示x,y直接连接
}
for(int i=1;i<=n;i++)
dis[i][i]=0;
//弗洛伊德
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(dis[i][j]>dis[i][k]+dis[k][j])
dis[i][j]=dis[i][k]+dis[k][j];
int q;int s,t;ll b;int distance;
ll sum;
cin>>q;
for(int i=0;i<q;i++)
{
cin>>s>>t>>b;
distance=dis[s][t];
int l=1,r=b;
while(l<r)
{
sum=0;
int mid=(l+r+1)/2;
for(int j=1;j<=distance;j++)
{
sum+=pow(mid,j);
if(sum>b)
break;
}
if(sum<=b)
l=mid;
else
r=mid-1;
}
sum=0;
for(int j=1;j<=distance;j++)
{
sum+=pow(l,j);
}
if(sum<=b)
cout<<l<<endl;
else
cout<<l-1<<endl;
}
return 0;
}