牛客网暑期ACM多校训练营(第一场) D 题解

队友说找用点的度数找规律,然后我就无从下手了。。。到最后也不知道怎么做。
赛后抛开了队友的找规律方法,发现n=8的,可以想到这题时间复杂度应该是n!或者2^n这种级别。
自然会想到直接枚举所有映射,因为图一到图一可能存在a2次映射,那么我们算图1和图2的映射总次数a1,答案中肯定重复了a2次,那么a1/a2就是我们求的答案。当然也可以hash来做。下面给出直接除的代码。

#include <bits/stdc++.h>
using namespace std;
int ma1[15][15],ma2[15][15];
int a[15];
int main()
{
    int n,m1,m2;
    while(cin>>n>>m1>>m2)
    {
        memset(ma1,0,sizeof(ma1));
        memset(ma2,0,sizeof(ma2));
        for(int i=1;i<=m1;i++)
        {
            int x,y;cin>>x>>y;
            ma1[x][y]=1;
            ma1[y][x]=1;
        }
        for(int i=1;i<=m2;i++)
        {
            int x,y;cin>>x>>y;
            ma2[x][y]=1;
            ma2[y][x]=1;
        }
        for(int i=1;i<=n;i++)
        a[i]=i;
        int a1=0,a2=0;
        do{
            int flag=1;
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            if(ma1[i][j]&&(!ma2[a[i]][a[j]])){flag=0;break;
            }
            a1+=flag;
        }while(next_permutation(a+1,a+1+n));
        for(int i=1;i<=n;i++)
        a[i]=i;
        do{
            int flag=1;
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            if(ma1[i][j]&&(!ma1[a[i]][a[j]])){
                flag=0;break;
            }
            a2+=flag;
        }while(next_permutation(a+1,a+1+n));
        cout<<a1/a2<<endl;
    }
    return 0;
}
全部评论
也可以把边集状压存下来,用set判重就好。 #include <bits/stdc++.h> using namespace std; const int N = 10; int G[N][N]; vector<pair<int, int>> edges; map<pair<int, int>, int> dic; int getid(int x, int y) { if (x > y) swap(x, y); assert(x < y); if (dic[{x, y}]) return dic[{x, y}]; return dic[{x, y}] = dic.size(); } long long check() { long long hash = 0; for (auto& e : edges) { int u = p[e.first], v = p[e.second]; if (G[u][v]) hash |= 1LL << getid(u, v); else return -1; } return hash; } int main() { int n, a, b; while (~scanf("%d%d%d", &n, &a, &b)) { memset(G, 0, sizeof(G)); dic.clear(); edges.clear(); for (int i = 0, u, v; i < a; i++) { scanf("%d%d", &u, &v); --u, --v; edges.emplace_back(u, v); } for (int i = 0, u, v; i < b; i++) { scanf("%d%d", &u, &v); --u, --v; G[u][v] = G[v][u] = 1; getid(u, v); } for (int i = 0; i < n; i++) p[i] = i; set<long long> s; do { int tmp = check(); if (~tmp) s.insert(tmp); } while (next_permutation(p, p + n)); int ans = s.size(); printf("%d\n", ans); } }
点赞 回复
分享
发布于 2018-07-19 21:38

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务