NOIP模擬賽 偶數度問題

2021-08-07 11:14:00 字數 2031 閱讀 6563

題目描述

給定乙個無向圖g,有n個節點,節點編號為1...n。圖g中已經連了m條邊。請你再連線k條邊,使得所有的節點的度數都是偶數。要求你再連線k條邊,使得所有的節點的度數都是偶數。

求有多少種連的方法。要求你連的k條邊中不能有重邊,但和已經連好的m條邊可以重。不允許自環的存在。求連邊的方法數。

輸入格式

第1行:3個整數,分別表示n(n≤1000),m(m≤n),k(k≤1000,k≤n*(n-1)/2)。

接下來m行每行2個整數x,y,描述了一條已經連線好的x和y的邊

輸出格式

第1行:1個整數,表示連邊的方法數。答案模10^9+7

輸入樣例

5 1 4

1 2輸出樣例 13

樣例說明

以下是13種兩邊的方法(只顯示新連的邊):

題解

首先,已經連好的m條邊並沒有過多的意義。對於已經連好的點,只關心它們的度數的奇偶性。可以假設連好的邊使得前p個點的度數是奇數。這樣問題可以轉化為:從乙個空白的無向圖開始,有多少種連邊的方法,使得前p個點的度數是奇數。

設f[i][j]表示用i條邊,使得j個點的度數為奇數的情況下連邊的方法數。

首先分類討論第i條邊連線的點的度數的奇偶性。

①如果連線的點是一奇一偶,那麼奇數點的個數不變:f[i][j]=f[i-1][j]*(n-j)*j

②如果連線兩個奇數點,那麼原來兩個點的度數是偶數:f[i][j]+=f[i−1][j−2]*c(j,2)

③如果連線兩個偶數點,那麼原來兩個點的度數是奇數:f[i][j]+=f[i−1][j+2]*c(n−j,2)

但這樣轉移的話無法保證沒有重邊。於是考慮第i條邊和之前的第x條邊重複的情況。x有i-1種取值。刪去第i條和第x條邊,所有的點的度數的奇偶性不變:

f[i][j]-=f[i-2][j]*(i-1)*( c(n,2)-(i-2) )

總的轉移方程是:

f[i][j]=f[i-1][j]*(n-j)*j + f[i-1][j-2]*c(j,2) + f[i-1][j+2]*c(n-j,2) - f[i-2][j]*(i-1)*( c(n,2)-(i-2) )

再去掉重複的方案數,答案為f[k][p]/k!。

#include#includetypedef long long ll;

const int inf=0x3f3f3f3f;

const int mod=1e9+7;

const int n=1005;

ll n, m, k, w, sum=1;

ll dp[n][n], esum, psum;

bool pot[n];

//設f[k][p]表示用k條邊,使得p個點的度數為奇數的情況下連邊的方法數。

//f[k][p]=f[k-1][p]*(n-p)*p + f[k-1][p-2]*c(p,2) + f[k-1][p+2]*c(n-p,2) - f[k-2][p]*(k-1)*( c(n,2)-(k-2) )

ll dfs( ll k, ll p )

ll exeu(ll a,ll b,ll c)

/*ax=b%c

ax=cy+b

cy=a-b%a

y=exeu( c%a, (b?a-b%a:0), a )

x=(c*y+b)/a

*/int main()

for( int i=1; i<=n; i++ ) psum+=pot[i];

memset( dp, -1, sizeof dp );

w=dfs( k, psum );

for( ll i=1; i<=k; i++ ) sum=sum*i%mod;

w=exeu( sum, w, mod );

printf( "%i64d\n", w );

return 0;

}

noip模擬賽 密碼

表示沒看懂演算法3 問題描述 有壓迫,就有反抗。mored的寵物在法庭的幫助下終於反抗了。作為乙隻聰明的寵物,他打算把魔法使mored的魔法書盜去,奪取mored的魔法能力。但mored怎麼會讓自己的魔法書輕易地被盜取?mored在魔法書上設定了乙個密碼鎖,密碼鎖上有乙個問題。施以斯臥鋪魔法吧,你有...

NOIP模擬賽 老師

題目描述 一座有n層的教學樓裡有一些學生,第i 0 i n 層有studentsi個學生。你被給定了乙個數k,如果第i層有x個學生,那麼這一層需要 x k 個老師。你可以調整每個學生的樓層,但是每個學生至多只能調整一層,就是說第i層的學生只能去第i 1層 如果有的話 第i層 第i 1層 如果i 1 ...

NOIP模擬賽 分錢

題目描述 兩個人在街上撿到了一些錢,這些錢共有n張,他們等了很久也沒有等來失主,於是決定把錢平分。但錢可能無法平分。他們先把能夠平分的錢盡量先平分了,使得剩下不能平分的錢盡量少。這些不能平分的錢怎麼辦呢他?他們決定拿去賭場裡面賭一把。他們運氣太好了,那些不能平分的錢變成了雙倍,於是他們就把那個錢分了...