首先你有一个\(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);
}