A Pair of Graphs

一道同构图的题目。大意就是给出两幅图,同时可以执行两种操作,分别是加边和删边,在A图上加边、删边的代价是Ia,Da;在B图上加边、删边的代价是Ib,Db。现在要通过这两种操作使得两幅图同构,问怎样的操作代价最小,求这个最小代价

因为数据范围很小,N<=8,所以可以直接枚举。具体见代码

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <cctype>
#include <string>
#include <queue>
#define debug printf("debug\n")
#define mst(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
const int maxn=1e5+5;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
/*在无向图中,关联一对顶点的无向边如果多于1条,则称这些边为平行边,
平行边的条数称为重数。在有向图中,关联一对顶点的有向边如果多于1条,
并且这些边的始点与终点相同(也就是它们的的方向相同),称这些边为平行边。
含平行边的图称为多重图,既不含平行边也不包含自环的图称为简单图*/
bool ga[10][10];
bool gb[10][10];
int main()
{
    int n;
    int es_a,es_bb;
    int kase=0;
    while(cin>>n>>es_a>>es_bb)
    {
        if(n==0&&es_a==0&&es_bb==0)        break;
        mst(ga,0);mst(gb,0);
        int ia,ib,da,db;
        cin>>ia>>ib>>da>>db;
        for(int i=0;i<es_a;i++){
            int x,y;
            scanf("%d %d",&x,&y);
            ga[x][y]=ga[y][x]=1;
        }
        for(int i=0;i<es_bb;i++){
            int x,y;
            scanf("%d %d",&x,&y);
            gb[x][y]=gb[y][x]=1;
        }
        int arr[10];
        int ans=INF;
        for(int i=0;i<n;i++)
            arr[i]=i;
        int fac=1;
        for(int i=1;i<=n;i++)        fac*=i;
        for(int k=0;k<fac;k++){
            int tmp=0;
            for(int i=0;i<n;i++){
                for(int j=i+1;j<n;j++){
                    if(ga[i][j]!=gb[arr[i]][arr[j]]){        //如果两个条边之间的关系不一致
                        if(ga[i][j])
                            tmp+=min(da,ib);
                        else
                            tmp+=min(ia,db);
                    }
                }
            }
            ans=min(ans,tmp);
            next_permutation(arr,arr+n);
        }
        printf("Case #%d: %d\n",++kase,ans);
    }
    return 0;
}