2019.7.14 义乌模拟赛 T4 city
作者:互联网
首先你有一个\(O(n^2logk)\)的显然做法:枚举重复路径两个端点,计算重复路径和非重复路径的长度,然后三分最大值即可。
这个东西显然过不去,发现瓶颈在三分上,考虑优化。
发现对于一个固定的重复路径长度,非重复路径肯定越短越好。
那么不就只用三分\(n\)次了?
时间复杂度就变成了\(O(n^2)\)
code:
#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define ll long long
#define db double
#define N 5000
#define M 50000
#define mod 1000000000
#define mod2 39989
#define eps (1e-7)
#define U unsigned int
#define it iterator
#define Gc() getchar()
#define Me(x,y) memset(x,y,sizeof(x))
using namespace std;
int n,m,k,ks,x,y,d[N+5][N+5],now,s1,t1,s2,t2,l,r,mid,Minn[N+5],a,b;db ans=1e9,pus;
struct yyy{int to,z;}tmp;
struct ljb{
int head,h[N+5];yyy f[N+5<<1];
I void add(int x,int y){f[++head]=(yyy){y,h[x]};h[x]=head;}
}s;queue<int> Q;
I void insert(int x,int y){Minn[x]=min(Minn[x],y);}
I db check(int mid,int now,int tot){
a=k-mid;pus=0;if(now)b=mid/now+1,pus+=(2.0/b)*(now-mid%now)+(mid%now)*(2.0/(b+1));
if(tot)b=a/tot+1,pus+=(1.0/b)*(tot-a%tot)+(a%tot)*(1.0/(b+1));return pus;
}
I void calc(int now,int tot){
l=0;r=k;while(l+1<r) mid=l+r>>1,(check(mid,now,tot)<=check(mid+1,now,tot)?r:l)=mid;ans=min(ans,min(check(l,now,tot),check(r,now,tot)));//printf("%d\n",l);
}
int main(){
freopen("city.in","r",stdin);freopen("city.out","w",stdout);
re int i,j;scanf("%d%d%d",&n,&m,&k);ks=k;Me(d,-1);Me(Minn,0x3f);for(i=1;i<=m;i++) scanf("%d%d",&x,&y),s.add(x,y),s.add(y,x);scanf("%d%d%d%d",&s1,&t1,&s2,&t2);
if(s1==t1&&s2==t2){printf("%.9lf\n",0);return 0;}
for(i=1;i<=n;i++){
d[i][i]=0;Q.push(i);while(!Q.empty()){
now=Q.front();Q.pop();for(j=s.h[now];j;j=tmp.z){
tmp=s.f[j];if(~d[i][tmp.to]) continue;d[i][tmp.to]=d[i][now]+1;Q.push(tmp.to);
}
}
}
insert(0,d[s1][t1]+d[s2][t2]);
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(~d[i][j]&&~d[s1][i]&&~d[s2][i]&&~d[t1][j]&&~d[t2][j])insert(d[i][j],d[s1][i]+d[s2][i]+d[t1][j]+d[t2][j]);
if(~d[i][j]&&~d[s1][i]&&~d[s2][j]&&~d[t1][j]&&~d[t2][i])insert(d[i][j],d[s1][i]+d[s2][j]+d[t1][j]+d[t2][i]);
}
}
for(i=0;i<=n;i++) if(Minn[i]<1e9) calc(i,Minn[i]);printf("%.9lf\n",ans);
}
标签:city,14,int,T4,mid,tot,now,pus,define 来源: https://www.cnblogs.com/275307894a/p/15013718.html