一道同构图的题目。大意就是给出两幅图,同时可以执行两种操作,分别是加边和删边,在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;
}