日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

ADPC2-G 希望

發(fā)布時間:2023/12/3 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ADPC2-G 希望 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

希望

題意:

有A,B兩棵樹,對于一個1到n的全排列a[i],讓樹A中的點i和樹B的節(jié)點a[i]連一條邊,希望指數(shù):兩棵樹和新加入的邊構(gòu)成的圖中,環(huán)長為m的環(huán)的個數(shù)。數(shù)組a[]可以任意交換位置,且任意,隨機(jī),不限次數(shù)的交換。計算出期望情況下,兩棵樹的希望指數(shù)
n≤300,3≤m≤7

題解:

期望=概率 * 對應(yīng)的權(quán)值
在本題中概率肯定是1n!\frac{1}{n!}n!1?,因此需要求所有情況下環(huán)長為m的環(huán)的個數(shù)
我們開始找環(huán)的分布情況,一定是左側(cè)的點和右側(cè)的點通過之間加的點形成環(huán),如圖,圖中環(huán)長為6

且所有環(huán)用到中間新建邊只能為兩條邊,可能會疑惑,為什么?像圖中情況,用到的新建邊的數(shù)量為4,不是2,但是圖中環(huán)的長度為8(這已經(jīng)是新建邊4所對應(yīng)的環(huán)最小長度),而題目保證所求環(huán)長<=7,剛好不行。也就是其實題目是隱含著新建邊最多用兩條,不可能更多

我們確定了中間邊只能用2,那就好說了,比如讓你求環(huán)為x的數(shù)量,x先減2,y=x-2,然后就是兩個樹一共構(gòu)成長度為y,因此我們預(yù)先處理出兩個子樹分別能組成長度為len的邊的數(shù)量,用桶來存。比如:tong1[i]:表示在樹A中長度為i的邊的數(shù)量。那么答案就:tong1[i]?tong2[m?i?2]?2.0?((n?2))tong1[i]*tong2[m-i-2]*2.0*((n-2))tong1[i]?tong2[m?i?2]?2.0?((n?2))
i是樹A需要提供的邊,m-i-2是樹B需要提供的邊,乘2.0是因為邊可以交叉和不交叉來,正好兩種,而最后(n-2)!是什么?我們之前說過最多用新增邊為2,那么說明左右各有兩個點要被占用(因為一個邊有兩個點),而其他的點可以任意排列,剩下的點就是(n-2)個,任意排列就是階乘
再講一些細(xì)節(jié):
比如樹上所有路徑長度,可以用floyd來求,因為答案要乘(n-2)!,而最終答案還要除以n!,所以直接除以n*(n-1)即可

代碼:

#include <bits/stdc++.h> #include <unordered_map> #define debug(a, b) printf("%s = %d\n", a, b); using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> PII; clock_t startTime, endTime; //Fe~Jozky const ll INF_ll= 1e18; const int INF_int= 0x3f3f3f3f; void read(){}; template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar) {x= 0;char c= getchar();bool flag= 0;while (c < '0' || c > '9')flag|= (c == '-'), c= getchar();while (c >= '0' && c <= '9')x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();if (flag)x= -x;read(Ar...); } template <typename T> inline void write(T x) {if (x < 0) {x= ~(x - 1);putchar('-');}if (x > 9)write(x / 10);putchar(x % 10 + '0'); } void rd_test() { #ifdef ONLINE_JUDGE #elsestartTime = clock ();freopen("data.in", "r", stdin); #endif } void Time_test() { #ifdef ONLINE_JUDGE #elseendTime= clock();printf("\nRun Time:%lfs\n", (double)(endTime - startTime) / CLOCKS_PER_SEC); #endif } const int maxn=400; vector<int>a[maxn],b[maxn],g[maxn]; int L[maxn]; int x[maxn][maxn]; int y[maxn][maxn]; int tong1[maxn],tong2[maxn]; int main() {//rd_test();int n,m;cin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){x[i][j]=1e9;y[i][j]=1e9;}}for(int i=1;i<n;i++){int u,v;read(u,v);x[u][v]=x[v][u]=1;}for(int i=1;i<n;i++){int u,v;read(u,v);y[u][v]=y[v][u]=1;}for(int k=1;k<=n;k++){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){x[i][j]=min(x[i][j],x[i][k]+x[k][j]);y[i][j]=min(y[i][j],y[i][k]+y[k][j]);}}}for(int i=1;i<=n;i++){for(int j=i+1;j<=n;j++){if(i==j)continue;if(x[i][j]==1e9)continue;if(y[i][j]==1e9)continue;tong1[x[i][j]]++;tong2[y[i][j]]++;}}double ans=0;for(int i=1;i<=m-3;i++){ans=ans+1.0*tong1[i]*tong2[m-i-2]*2.0/(1.0*n*(n-1));}printf("%.4lf\n",ans);//Time_test(); }

總結(jié)

以上是生活随笔為你收集整理的ADPC2-G 希望的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。