当前位置:网站首页>【CodeForces908H】New Year and Boolean Bridges (FWT)
【CodeForces908H】New Year and Boolean Bridges (FWT)
2022-06-11 07:37:00 【CaptainHarryChen】
The main idea of the topic
For a directed graph ( 1 ≤ n ≤ 47 ) (1\leq n\leq47) (1≤n≤47), Definition f ( u , v ) f(u,v) f(u,v) The value of is true, If and only if there is a path that makes u u u Can walk to v v v
Give me a “ Adjacency matrix ” A [ i ] [ j ] A[i][j] A[i][j]:
If A[i][j]=='A', be f(u,v) and f(v,u) by true
If A[i][j]=='X', be f(u,v) xor f(v,u) by true
If A[i][j]=='O', be f(u,v) or f(v,u) by true
( Keep the matrix symmetric )
To construct a directed graph , Satisfy adjacency matrix A, At least how many edges are needed .
Answer key
First of all, we can know that the whole picture must be connected ( Neither of the above conditions says that the two points are completely disconnected )
then , If A[i][j]=='A', be i i i And j j j It must be in a strongly connected block , First, all strongly connected blocks are treated with the union search set .
One point is size(size>=2) Strongly connected block of , need size This strongly connected block is connected by two edges ( A ring ). Let's have a total of m A strong connection block , Then you need m-1 Edges connect connected blocks into a tree .
And after collecting and processing , Some strongly connected blocks can be merged .
obviously , The fewer connected blocks the better ( Merge once , One less tree edge ), however , There is xor Strongly connected blocks of a relation cannot be merged .
siz>=2 Has the most strongly connected blocks 23 individual , Use shape pressure to express , g k [ S ] g_k[S] gk[S] Signify a company k Tree edge , The set is S Whether the connected blocks of can be connected .
Preprocess first f [ S ] = g 0 [ S ] f[S]=g_0[S] f[S]=g0[S], About to exist in the collection xor The two connected blocks of the relationship are marked as 0, The rest are 1
set up T by S Subset , Transfer
g k + 1 [ S ] ∣ ∣ = g k [ T ] & & g k [ S x o r T ] g_{k+1}[S]\ ||=g_k[T]\ \&\&\ g_k[S\ xor\ T] gk+1[S] ∣∣=gk[T] && gk[S xor T]
In fact, such transfer can also (S And T No restrictions )
g k + 1 [ S o r T ] + = g k [ S ] × g k [ T ] g_{k+1}[S\ or\ T]\ +=g_k[S]\times g_k[T] gk+1[S or T] +=gk[S]×gk[T]
Exactly or convolution , You can use FWT do
So we can go from g 0 g_0 g0 Start , Keep rolling f f f, until g k [ a l l ] g_k[all] gk[all] Not for 0, You need to k Tree edge .
In order to simplify the , On each roll f f f after , Don't go back FWT Back again , Each position pair can be calculated in advance all The contribution of , Only calculate all It's just a factor of
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=50,MAXS=(1<<24)+10;
int n;
char adj[MAXN][MAXN];
int fa[MAXN],siz[MAXN];
int Root(int u)
{
if(fa[u]==0)
return u;
return fa[u]=Root(fa[u]);
}
void Union(int u,int v)
{
int r1=Root(u),r2=Root(v);
if(r1==r2)
return;
fa[r1]=r2;
siz[r2]+=siz[r1];
}
void FWT(int A[],int n)
{
for(int i=1;i<n;i<<=1)
for(int j=0;j<n;j+=(i<<1))
for(int l=j,r=j+i;l<i+j;l++,r++)
A[r]+=A[l];
}
int m,id[MAXN];
int f[MAXS],g[MAXS],a[MAXS];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%s",adj[i]+1);
for(int i=1;i<=n;i++)
siz[i]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<i;j++)
if(adj[i][j]=='A')
Union(i,j);
int ans=0;
for(int i=1;i<=n;i++)
{
int r=Root(i);
if(r==i)
{
if(siz[r]>=2)
id[r]=++m;
ans+=siz[r];
}
}
if(m==0)
{
printf("%d\n",n-1);
return 0;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(adj[i][j]=='X')
{
int r1=Root(i),r2=Root(j);
if(r1==r2)
{
puts("-1");
return 0;
}
if(id[r1]&&id[r2])
f[(1<<(id[r1]-1))|(1<<(id[r2]-1))]=1;
}
for(int s=1;s<(1<<m);s++)
for(int i=1;i<=n;i++)
if(s&(1<<(i-1)))
f[s]|=f[s^(1<<(i-1))];
for(int s=0;s<(1<<m);s++)
f[s]=f[s]^1;
FWT(f,1<<m);
for(int i=0;i<(1<<m);i++)
a[i]=1;
for(int i=1;i<(1<<m);i<<=1)
for(int j=0;j<(1<<m);j+=(i<<1))
for(int l=j;l<i+j;l++)
a[l]*=-1;
for(int i=0;i<(1<<m);i++)
g[i]=1;
for(int i=1;;i++)
{
int tmp=0;
for(int j=0;j<(1<<m);j++)
g[j]*=f[j];
for(int j=0;j<(1<<m);j++)
tmp+=g[j]*a[j];
if(tmp)
{
printf("%d\n",ans+i-1);
return 0;
}
}
return 0;
}
边栏推荐
- Rabin Miller prime test
- Multi thread review summary parsing volatile keyword
- QT picture adaptive display control
- [noip2016 d1t3] changing classrooms (expectation dp+floyd) (trap of extreme thinking!)
- 如果要存 IP 地址,用什么数据类型比较好?99%人都会答错!
- Miscellany C language
- [STL source code analysis] summary notes (5): a good helper for understanding iterators --list
- [analysis of STL source code] summary note (4): behind the scenes hero allocator
- [Oracle database] mammy tutorial day02 use of database management tool sqlplus
- nosqlzoo刷题-1
猜你喜欢
随机推荐
二本畢業,銀行外包測試工作 4 個月有餘。聊聊一些真實感受 ...
[STL source code analysis] summary notes (9): set/multiset and map/multimap
QObject usage skills -- control function class
Uoj 551 [unr 4] campus stroll [good polynomial questions (FOG)]
Configuration software -- control import
Aiop introduction
Simple configuration of vscade
Ffmpeg extraction package format extracts AAC and customizes adtc header to realize arbitrary frame decoding
【编译原理】05-语法制导的语义计算——基于翻译模式的语义计算
Compound RateModel合约解析
[noip2016 d1t3] changing classrooms (expectation dp+floyd) (trap of extreme thinking!)
You got 8K in the 3-year function test, but you were actually pretending to work hard
[STL source code analysis] summary notes (7): ingenious deque
[STL source code analysis] summary notes (5): a good helper for understanding iterators --list
20200810 T2 dispatch money
【AtCoder1980】Mysterious Light(数学模拟)
Summary of classic interview questions
C language three chess games
[Oracle database] mammy tutorial day03 Sorting Query
C memory alignment


![20200727 T2 small w playing game [generating function (binomial inversion technique)]](/img/a5/ae2192f4f37232cdcb01e81ad0297c.jpg)





