码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 4671: 异或图

时间:2018-01-07 20:14:30      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:stream   stat   for   blank   nbsp   discuss   连通图   data   led   

4671: 异或图

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 61  Solved: 39
[Submit][Status][Discuss]

Description

定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与
G2 中的出现次数之和为 1, 那么边 (u, v) 在 G 中, 否则这条边不在 G 中.
现在给定 s 个结点数相同的图 G1...s, 设 S = {G1, G2, . . . , Gs}, 请问 S 有多少个子集的异
或为一个连通图?

 

Input

第一行为一个整数s, 表图的个数.
接下来每一个二进制串, 第 i 行的二进制串为 gi, 其中 gi 是原图通过以下伪代码转化得
到的. 图的结点从 1 开始编号, 下面设结点数为 n.
Algorithm 1 Print a graph G = (V, E)
for i = 1 to n do
for j = i + 1 to n do
if G contains edge (i, j) then
print 1
else
print 0
end if
end for
end for
 2 ≤ n ≤ 10,1 ≤ s ≤ 60.

 

Output

输出一行一个整数, 表示方案数

 

Sample Input

3
1
1
0

Sample Output

4
这个题还不很明白,对斯特林数还不够了解
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 20
using namespace std;
int co[maxn],n,m,s,tot;
long long fac[maxn],two[70],eq[70],ans;
bool dis[70][maxn][maxn];
char h[maxn*maxn];
void dfs(int x,int m){
    if(x==n+1){
        int top=0;
        for(int i=1;i<=n-1;i++)
            for(int j=i+1;j<=n;j++){
                if(co[i]!=co[j]){
                    long long t=0;
                    for(int k=1;k<=s;k++)if(dis[k][i][j])t+=two[k-1];
                    for(int k=1;k<=top;k++)if((t^eq[k])<t)t^=eq[k];
                    if(t)eq[++top]=t;
                }
            }
        ans+=fac[m-1]*two[s-top];
        return;
    }
    for(int i=1;i<=m+1;i++){
        co[x]=i;
        dfs(x+1,m+(i>m));
    }
}
int read(){
    char ch=getchar();
    while (ch<0||ch>1) ch=getchar();
    return ch-0;
}
int main(){
    scanf("%d%s",&s,h+1);
    int len=strlen(h+1);
    for(n=1;n<=10;n++)if(n*(n-1)/2==len)break;
    long long t=0;
    for(int i=1;i<=n-1;i++)
    for(int j=i+1;j<=n;j++)
        dis[1][i][j]=h[++t]-0;
    for(int k=2;k<=s;k++)
    for(int i=1;i<=n-1;i++)
    for(int j=i+1;j<=n;j++)
        dis[k][i][j]=read();
    fac[0]=two[0]=1;
    for(int i=1;i<=n;i++)fac[i]=-1LL*fac[i-1]*i;
    for(int i=1;i<=s;i++)two[i]=two[i-1]*2;
    dfs(1,0);
    cout<<ans<<endl;
}

 

bzoj 4671: 异或图

标签:stream   stat   for   blank   nbsp   discuss   连通图   data   led   

原文地址:https://www.cnblogs.com/thmyl/p/8229044.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!