题目链接

题意 : 给出两幅顶点数一样的图 G1、G2 ,现在要求在 G2 中选出一些边集、使之构成一幅新的图 G ,要求 G 要与 G1 同构,现在要你统计合法的 G 有多少种

分析 : 

图的同构是离散数学里面图论的一个概念、具体的可以看 这里

判断两幅图是否是同构的至今貌似还是 NP 问题

由于顶点数最多只有 8、同时意味着边最多只有 28

那么可以由此想到 O(n!) 枚举所有的顶点的双射 (实际就是枚举全排列)

考察每个双射下两图是否能够构成同构关系

判断是否构成双射只要考察其邻接矩阵是否能一样即可

这就意味着去选出 G2 这副图中的某些边集

使得当前枚举到的双射能够使得 G1 和 G2 同构

由于边不多、所以可以状态压缩这些边集

存到一个 set 中进行去重、最后 set 的大小即为答案

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

还有另外一种做法就是

枚举双射计算出 G1 和 G2 同构方案数

然后再计算出 G1 和 G1 自己的自同构方案数

最后答案就是 ( G1 和 G2 同构方案数 ) / ( G1 和 G1 自己的自同构方案数 )

说实话、这个东西、我并不是很理解...........

#include<bits/stdc++.h>
#define LL long long
#define ULL unsigned long long

#define scl(i) scanf("%lld", &i)
#define scll(i, j) scanf("%lld %lld", &i, &j)
#define sclll(i, j, k) scanf("%lld %lld %lld", &i, &j, &k)
#define scllll(i, j, k, l) scanf("%lld %lld %lld %lld", &i, &j, &k, &l)

#define scs(i) scanf("%s", i)
#define sci(i) scanf("%d", &i)
#define scd(i) scanf("%lf", &i)
#define scIl(i) scanf("%I64d", &i)
#define scii(i, j) scanf("%d %d", &i, &j)
#define scdd(i, j) scanf("%lf %lf", &i, &j)
#define scIll(i, j) scanf("%I64d %I64d", &i, &j)
#define sciii(i, j, k) scanf("%d %d %d", &i, &j, &k)
#define scddd(i, j, k) scanf("%lf %lf %lf", &i, &j, &k)
#define scIlll(i, j, k) scanf("%I64d %I64d %I64d", &i, &j, &k)
#define sciiii(i, j, k, l) scanf("%d %d %d %d", &i, &j, &k, &l)
#define scdddd(i, j, k, l) scanf("%lf %lf %lf %lf", &i, &j, &k, &l)
#define scIllll(i, j, k, l) scanf("%I64d %I64d %I64d %I64d", &i, &j, &k, &l)

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define lowbit(i) (i & (-i))
#define mem(i, j) memset(i, j, sizeof(i))

#define fir first
#define sec second
#define VI vector<int>
#define ins(i) insert(i)
#define pb(i) push_back(i)
#define pii pair<int, int>
#define mk(i, j) make_pair(i, j)
#define all(i) i.begin(), i.end()
#define pll pair<long long, long long>

#define _TIME 0
#define _INPUT 0
#define _OUTPUT 0
clock_t START, END;
void __stTIME();
void __enTIME();
void __IOPUT();
using namespace std;

 + ;

int G1[maxn][maxn];
int G2[maxn][maxn];

map<pii, int> mp;
set<LL> ans;

int main(void){__stTIME();__IOPUT();

    int n, m1, m2;

    while(~sciii(n, m1, m2)){

        mem(G1, );
        mem(G2, );
        ans.clear();
        mp.clear();

        ; i<m1; i++){
            int u, v;
            scii(u, v);
            G1[u][v] = G1[v][u] = ;
        }

        ; i<m2; i++){
            int u, v;
            scii(u, v);
            if(u < v) swap(u, v);
            mp[mk(u,v)] = i;
            G2[u][v] = G2[v][u] = ;
        }

        int idx[maxn];
        ; i<=n; i++) idx[i] = i;

        do{
            LL state = ;
            bool ok = true;
            ; i<=n; i++){///判断是否能构成同构
                ; j<=n; j++){
                    if(G1[i][j] && !G2[idx[i]][idx[j]]){///只考虑G1有边关联的两个顶点的情况
                        ok = false;
                        break;
                    }else{
                        if(G1[i][j]){
                            int u = idx[i];
                            int v = idx[j];
                            if(u < v) swap(u, v);
                            state |= (1LL<<mp[mk(u,v)]);///状态压缩
                        }
                    }
                }
                if(!ok) break;
            }

            if(!ok) continue;

            ans.ins(state);

        }, idx++n));

        printf("%d\n", (int)ans.size());
    }

__enTIME();;}

void __stTIME()
{
    #if _TIME
        START = clock();
    #endif
}

void __enTIME()
{
    #if _TIME
        END = clock();
        cerr<<"execute time = "<<(double)(END-START)/CLOCKS_PER_SEC<<endl;
    #endif
}

void __IOPUT()
{
    #if _INPUT
        freopen("in.txt", "r", stdin);
    #endif
    #if _OUTPUT
        freopen("out.txt", "w", stdout);
    #endif
}

Nowcoder Two Graphs ( 图的同构 )的更多相关文章

  1. USTC 1119 graph 图的同构

    USTC 1119 图的同构的严格定义可以参考离散数学:The simple graphs G1=(V1,E1) and G2=(V2,E2)are isomorphic if there exist ...

  2. 2018牛客网暑期ACM多校训练营(第一场) D - Two Graphs - [无向图同构]

    题目链接:https://www.nowcoder.com/acm/contest/139/D 题目描述 Two undirected simple graphs  and  where  are i ...

  3. Two Graphs 牛客网暑期ACM多校训练营(第一场)D 图论基础知识 全排列

    链接:https://www.nowcoder.com/acm/contest/139/D来源:牛客网 Two undirected simple graphs and where are isomo ...

  4. tunning-Instruments and Flame Graphs

    On mac os, programs may need Instruments to tuning, and when you face too many probe messages, you'l ...

  5. Intel® Threading Building Blocks (Intel® TBB) Developer Guide 中文 Parallelizing Data Flow and Dependence Graphs并行化data flow和依赖图

    https://www.threadingbuildingblocks.org/docs/help/index.htm Parallelizing Data Flow and Dependency G ...

  6. 特征向量-Eigenvalues_and_eigenvectors#Graphs

    https://en.wikipedia.org/wiki/Eigenvalues_and_eigenvectors#Graphs A               {\displaystyle A} ...

  7. UVALive 6508 Permutation Graphs

    Permutation Graphs Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit ...

  8. NowCoder猜想(素数筛法+位压缩)

    在期末被各科的大作业碾压快要窒息之际,百忙之中抽空上牛客网逛了逛,无意中发现一道好题,NowCoder猜想,题意很明显,就是个简单的素数筛法,但竟然超内存了,我晕(+﹏+)~  明明有 3 万多 k ...

  9. [nowCoder] 两个不等长数组求第K大数

    给定两个有序数组arr1和arr2,在给定一个整数k,返回两个数组的所有数中第K小的数.例如:arr1 = {1,2,3,4,5};arr2 = {3,4,5};K = 1;因为1为所有数中最小的,所 ...

随机推荐

  1. poj2385(基础DP)

    题目链接:http://poj.org/problem?id=2385 题意:最开始Bessie站在树1下面,每一个单位时间有颗苹果从树1或者树2上落下来.每个单位时间Bessie可以移动一次位置,时 ...

  2. 面向对象编程 OOP

    OOP,Object Oriented Programming,原来就是面向对象的编程. 面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物. OOD,Object Or ...

  3. HDU3336 Count the string(kmp

    It is well known that AekdyCoin is good at string problems as well as number theory problems. When g ...

  4. 分层最短路(牛客第四场)-- free

    题意: 给你边权,起点和终点,有k次机会把某条路变为0,问你最短路是多长. 思路: 分层最短路模板题.题目有点坑(卡掉了SPFA,只能用dijkstra跑的算法). #include<iostr ...

  5. nodejs---crypto模块MD5签名

    1.MD5是一种常用的哈希算法,用于给任意数据一个“签名”.这个签名通常用一个十六进制的字符串表示: /*md5签名*/ /*引入crypto模块*/ const crypto = require(' ...

  6. 关于redis的几件小事(三)redis的数据类型与使用场景

    1.string 这是最基本的类型了,就是普通的set和get,做简单的kv缓存. 2.hash 这个是类似map的一种结构,这个一般就是可以将结构化的数据,比如一个对象(前提是这个对象没嵌套其他的对 ...

  7. 部署Dashboard,监控应用

    部署web UI(dashboard)用于监控node资源 参见文档:https://blog.csdn.net/networken/article/details/85607593 官网:https ...

  8. 手把手教你查看网站遭受到的Web应用攻击类型

    常见Web应用攻击类型有:webshell.SQL注入.文件包含.CC攻击.XSS跨站脚本攻击.敏感文件访问.远程命令.恶意扫描.代码执行.恶意采集.特殊攻击.其他攻击十二种攻击类型. 如何查看网站遭 ...

  9. QString与QByteArray互相转换的方法

    本文转载自http://blog.csdn.net/daa20/article/details/51674753 // QString转QByteArray方法 //Qt5.3.2 QString s ...

  10. 关于STM32中printf函数的重定向问题

    printf函数一般是打印到终端的,stm32芯片调试中经常需要用到串口来打印调试信息,那能不能用串口实现类似windows的Console中的printf呢? 答案是肯定的,那就是printf函数的 ...