生活随笔
收集整理的這篇文章主要介紹了
牛客练习赛74 E CCA的期望(算概率的技巧+floyd处理)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
牛客地址 題目描述 是否經常有藝術創(chuàng)作的沖動,但卻限于水平無法描繪?那就交給隨機吧! 給定一張 n 個點 m 條邊的無向帶邊權連通圖,點有顏色,為黑或白,保證無自環(huán)和重邊。 定義一次操作為:隨機選擇兩個不同的點,將它們之間的最短路上的點全部染黑(若有多條最短路就都染黑)。 現(xiàn)在你想知道,經過 k 次操作后,黑色點的期望個數(shù)是多少 。
思路 :算這個的期望,我們可以轉化為每個點對期望的貢獻,既算出每個點變成黑色的概率。 任意選擇兩個不同的點,那么就有總數(shù) cnt=n*(n-1)/2; 假設經過i點的最短數(shù)次數(shù)為y(這個可以由floyd算法算出); 如果該點的顏色本來就為黑色,那么期望貢獻為1; 否則,選擇k次,至少一次選擇的路徑含有該點的期望就為(1-(1-y/cnt)^k)(連續(xù)k次都沒有選擇到 反向思考) 取模除法要使用逆元! 細節(jié)看代碼:
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <bitset>
#define INF 0x3f3f3f3f3f3f3f3f
#define inf 0x3f3f3f3f
#define FILL(a,b) (memset(a,b,sizeof(a)))
#define re register
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(a) ((a)&-(a))
#define ios std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
#define fi first
#define rep(i,n) for(int i=0;(i)<(n);i++)
#define rep1(i,n) for(int i=1;(i)<=(n);i++)
#define se second using namespace std
;
typedef long long ll
;
typedef unsigned long long ull
;
typedef pair
< ll
, ll
> pii
;
const ll mod
= 1023694381 ;
const ll N
= 3e6 + 10 ;
const double eps
= 1e-6 ;
const double pi
= acos ( - 1 ) ;
ll
gcd ( ll a
, ll b
) { return ! b
? a
: gcd ( b
, a
% b
) ; }
int dx
[ 8 ] = { 1 , 0 , - 1 , 0 , 1 , 1 , - 1 , - 1 } , dy
[ 8 ] = { 0 , 1 , 0 , - 1 , 1 , - 1 , 1 , - 1 } ;
int n
, m
, k
;
ll dis
[ 1000 ] [ 1000 ] ;
int c
[ 1000 ] ;
int sum
[ 1000 ] ;
ll
pow1 ( ll a
, ll b
) { ll ans
= 1 ; while ( b
) { if ( b
& 1 ) ans
= ( ans
* a
) % mod
; a
= ( a
* a
) % mod
; b
/ = 2 ; } return ans
;
}
void floyd ( )
{ for ( int k
= 1 ; k
<= n
; k
++ ) { for ( int i
= 1 ; i
<= n
; i
++ ) { for ( int j
= 1 ; j
<= n
; j
++ ) { dis
[ i
] [ j
] = min ( dis
[ i
] [ k
] + dis
[ k
] [ j
] , dis
[ i
] [ j
] ) ; } } }
}
void solve ( )
{ cin
>> n
>> m
>> k
; for ( int i
= 1 ; i
<= n
; i
++ ) { for ( int j
= 1 ; j
<= n
; j
++ ) { if ( i
== j
) dis
[ i
] [ j
] = 0 ; else dis
[ i
] [ j
] = ( ll
) 1e15 ; } } for ( int i
= 1 ; i
<= n
; i
++ ) cin
>> c
[ i
] ; for ( int i
= 1 ; i
<= m
; i
++ ) { ll u
, v
, w
; cin
>> u
>> v
>> w
; dis
[ u
] [ v
] = w
; dis
[ v
] [ u
] = w
; } floyd ( ) ; for ( int i
= 1 ; i
<= n
; i
++ ) { for ( int j
= i
+ 1 ; j
<= n
; j
++ ) { for ( int k
= 1 ; k
<= n
; k
++ ) { if ( dis
[ i
] [ j
] == dis
[ i
] [ k
] + dis
[ k
] [ j
] ) sum
[ k
] ++ ; } } } ll cnt
= ( ( n
- 1 ) * n
) / 2 ; ll inv
= pow1 ( pow1 ( cnt
, k
) , mod
- 2 ) % mod
; ll ans
= 0 ; for ( int i
= 1 ; i
<= n
; i
++ ) { if ( c
[ i
] == 1 ) ans
= ( ans
+ 1 ) % mod
; else { ans
= ( ans
+ ( ( 1 - ( pow1 ( cnt
- sum
[ i
] , k
) * inv
) % mod
+ mod
) % mod
) ) % mod
; } } cout
<< ans
<< endl
;
}
int main ( )
{ ios
int T
; T
= 1 ; while ( T
-- ) { solve ( ) ; } return 0 ;
}
總結
以上是生活随笔 為你收集整理的牛客练习赛74 E CCA的期望(算概率的技巧+floyd处理) 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內容還不錯,歡迎將生活随笔 推薦給好友。