小明国庆节准备去某星系进行星际旅行,这个星系里一共有 n 个星球,其中布置了 m 道双向传送门,第 i道传送门可以连接 ai,bi 两颗星球(ai≠bi 且任意两颗星球之间最多只有一个传送门)。
他看中了一款 “旅游盲盒”,一共有 Q个盲盒,第 i个盲盒里的旅行方案规定了旅行的起始星球 xi 和最多可以使用传送门的次数 yi。只要从起始星球出发,使用传送门不超过规定次数能到达的所有星球都可以去旅行。
小明关心在每个方案中有多少个星球可以旅行到。小明只能在这些盲盒里随机选一个购买,他想知道能旅行到的不同星球的数量的期望是多少。
输入格式
输入共 m+Q+1 行。
第一行为三个正整数 n,m,Q 。
后面 m行,每行两个正整数 ai,bi。
后面 Q 行,每行两个整数 xi,yi 。
输出格式
输出共一行,一个浮点数(四舍五入保留两位小数)。
样例输入
3 2 3
1 2
2 3
2 1
2 0
1 1
样例输出
2.00
样例说明
第一个盲盒可以旅行到 1,2,3。
第二个盲盒可以旅行到 2。
第三个盲盒可以旅行到 1,2。
所以期望是 (3+1+2)/3=2.00。
import java.util.*;
public class Main{
static int n,m,Q;
static int[][] con;
public static void main(String []args) {
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
m=sc.nextInt();
Q=sc.nextInt();
con=new int [n+1][n+1];
for(int i=1;i<=n;i++)
{
Arrays.fill(con[i], 3010);//将第i行所有元素数值都设置为3010,表示两个星球之间无传送门,权重为无穷
}
for(int i=1;i<=n;i++)
{
con[i][i]=0;//星球到自己本身权重设为0
}
for(int i=0;i<m;i++)
{
int a=sc.nextInt();
int b=sc.nextInt();
con[a][b]=1;//a,b星球之间有双向传送门,权重为1
con[b][a]=1;
}
for(int k=1;k<=n;k++)//k是i,j两个节点的中间节点
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
con[i][j]=Math.min(con[i][j],con[i][k]+con[k][j] );//检查通过中间节点k的路径是否比直接路径更短
}
}
}
int num=0;
for(int i=0;i<Q;i++)
{
int x=sc.nextInt();
int y=sc.nextInt();
int count=0;
for(int j=1;j<=n;j++)
{
if(con[x][j]<=y)//从起始星球x出发,使用传送门不超过规定的次数y
{
count++;//例如,x=2,y=1,则con[2][1],con[2][2],con[2][3]符合,有三种方案
}
}
num+=count;
}
System.out.printf("%.2f",(double)num/Q);
}
}