邊的染色 dfs 思維

2021-10-05 16:42:31 字數 1677 閱讀 9036

題目描述

小團有一張n個點,m條邊的無向圖g,有些邊上已經被標記了0或1,表示它的邊權。

現在你需要給剩下的邊標記邊權為0或1,求有幾種標記的方式滿足:

對於g中任意乙個環,裡面所有邊的邊權的異或值為0。

環的定義如下:

對於任意k(k≥2)個點,若對於所有的i

思路:此題的巧妙之處在於將邊權賦值為0或1,轉換成連線邊的兩點賦值0或1的異或值。

1、首先,在乙個n個點的環中,這n條邊的異或和 化為這n個點的異或和時,每個點被異或兩次,所以不管怎麼賦值最後的異或和都是0。而點的賦值方式是2^n種,所以邊的賦值方式是點賦值方式的一半2 ^ (n-1),因為對於兩個點的四種組合方式得到的邊權只用兩種,例如:0 ^ 0 = 0 , 1 ^ 1 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1; 所以是一半。

2、其次,若在這n個點的環中,假設有1個聯通塊已經被賦過邊權了,且這個連通塊的大小為k,那麼這個環的方案數就應該為 2 ^(n-1)/2 ^(k-1) ,設這個環中還沒有被賦值的邊為m,此時其實就是2 ^ m;

3、再深入分析,環的情況可以適用到乙個聯通圖中,因為在環中的邊的賦值其實已經相當於沒有限制了,所以將不同連通塊的2^m相乘起來就是答案。

4、接下來也是關鍵一步,判斷原始邊權值已經不滿足環中異或和為0。接下來所操作的都是在已經賦過值的邊所組成的連通塊內,在這個連通塊內,當乙個點的權值確定時,其他的點就都確定了,所以我們便可以確定是否矛盾。

#include

using

namespace std;

const

int mod =

998244353

;const

int n =

1e5+7;

int h[n]

,e[n*2]

,ne[n*2]

,w[n*2]

,idx;

int p[n]

,cnt;

int color[n]

,vis[n]

;void

add(

int a,

int b,

int c)

intfind

(int x)

void

dfs(

int x,

int col)

//判斷原始賦值是否矛盾 ,染色法}}

void

dfs2

(int x)

//每個連通塊(已經被賦值)大小

}int

main()

k = n-k;

//總的方案數

for(

int i=

1;i<=n;i++)}

memset

(color,-1

,sizeof color)

;for

(int i=

1;i<=n;i++

)long

long ans=1;

for(

int i=

1;i<=k;i++

) ans = ans*

2%mod;

printf

("%lld\n"

,ans)

;return0;

}

海戰(dfs染色)

在峰會期間,武裝部隊得處於高度戒備。警察將監視每一條大街,軍隊將保衛建築物,領空將布滿了f 2003飛機。此外,巡洋船隻和艦隊將被派去保護海岸線。不幸的是因為種種原因,國防海軍部僅有很少的幾位軍官能指揮大型海戰。因此,他們考慮培養一些新的海軍指揮官,他們選擇了 海戰 遊戲來幫助學習。在這個著名的遊戲...

分考場 DFS 染色問題

資源限制 時間限制 1.0s 記憶體限制 256.0mb 問題描述 n個人參加某項特殊考試。為了公平,要求任何兩個認識的人不能分在同乙個考場。求是少需要分幾個考場才能滿足條件。輸入格式 第一行,乙個整數n 1輸出格式 一行乙個整數,表示最少分幾個考場。樣例輸入58 1 21 3 1 42 3 2 4...

樹上dfs 思維

the number lamp a i,it is hanging on and 0,if is there is no such lamp 表示的是祖先的序號 題目中的坑 應該自下而上的判斷子樹的累加和是否滿足條件。如果是自上而下的判斷,一旦該樹的子樹有滿足條件的,去掉子樹後又滿足條件這種情況是無...