題目描述思路:此題的巧妙之處在於將邊權賦值為0或1,轉換成連線邊的兩點賦值0或1的異或值。小團有一張n個點,m條邊的無向圖g,有些邊上已經被標記了0或1,表示它的邊權。
現在你需要給剩下的邊標記邊權為0或1,求有幾種標記的方式滿足:
對於g中任意乙個環,裡面所有邊的邊權的異或值為0。
環的定義如下:
對於任意k(k≥2)個點,若對於所有的i
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 表示的是祖先的序號 題目中的坑 應該自下而上的判斷子樹的累加和是否滿足條件。如果是自上而下的判斷,一旦該樹的子樹有滿足條件的,去掉子樹後又滿足條件這種情況是無...