n个点 ,m条边 , 删掉一些边使得从u到v不连通;
在删掉的边权最小的前提下令删掉的边尽可能小,
求 [sum of the remainder roads' value]/[the amount of removed roads]
即 剩下边权和/删边条数
首先 : 剩下剩下边权和 为定值 = 最小割(最大流)
也就是要求 最少的删边条数
那么每条边 w 扩大10000倍 + 1 = 10000w + 1 。
这个时候求的最小割x ,也就 x = answer*10000 + 最少删边数
而x远远大于 边数 , 那么x %10000 = 最少删边数
const int inf = 1000000000 ;
const int maxn = 20000 , maxm = 500000 ;
struct Edge{
int v , f ,next ;
Edge(){}
Edge(int _v , int _f , int _next):v(_v) ,f(_f),next(_next){}
};
int sourse , meet ;
int id ;
Edge e[maxm*2 + 10] ;
int g[maxn + 10] ;
void add(int u , int v , int f){
e[++id] = Edge(v , f ,g[u]) ;
g[u] = id ;
e[++id] = Edge(u , 0 , g[v]) ;
g[v] = id ;
}
queue <int> que ;
bool vis[maxn + 10] ;
int dist[maxn + 10] ;
void bfs(){
memset(dist , 0 , sizeof(dist)) ;
while(! que.empty()) que.pop() ;
que.push(sourse) ;
vis[sourse] = 1 ;
while(! que.empty()){
int u = que.front() ; que.pop() ;
for(int i = g[u] ; i ; i = e[i].next){
int v = e[i].v ;
if(e[i].f && !vis[v]){
que.push(v) ;
dist[v] = dist[u] + 1 ;
vis[v] = 1 ;
}
}
}
}
int dfs(int u , int delta){
if(u == meet) return delta ;
int ans = 0 ;
for(int i = g[u] ; i && delta ; i = e[i].next){
int v = e[i].v ;
if(e[i].f && dist[v] == dist[u] + 1){
int d = dfs(v , min(delta , e[i].f)) ;
e[i].f -= d ;
e[i^1].f += d ;
delta -= d ;
ans += d ;
}
}
return ans ;
}
int maxflow(){
int ans = 0 ;
while(1){
memset(vis , 0 , sizeof(vis)) ;
bfs() ;
if(! vis[meet]) return ans ;
ans += dfs(sourse , inf) ;
}
}
void init(){
memset(g , 0 , sizeof(g)) ;
id = 1 ;
}
int main(){
int i , n , m , t , u , v , w , s , sum ;
cin>>t ;
while(t--){
init() ;
sum = 0 ;
scanf("%d%d%d%d" , &n , &m , &sourse , &meet) ;
for(i = 0 ; i < m ; i++){
scanf("%d%d%d" , &u , &v , &w) ;
add(u , v , w*10000 + 1) ;
add(v , u , w*10000 + 1) ;
sum += w ;
}
s = maxflow() ;
if(s == 0) puts("Inf") ;
else{
sum -= s/10000 ;
printf("%.2lf\n" , double(sum) / (s%10000) ) ;
}
}
return 0 ;
}