hdu2464 A Pair of Graphs 线段树

//给两个顶点数相同的图
//I_A , I_B, D_A , D_B ;分别为增加A图,B图的一个边,删除A图,B图的一个边的cost
//问最少需要花费多少使得两幅图同构
//由于n很小,可以暴力枚举A的每一个点对应B图的点对应关系,然后就是对应边如果一幅图有
//另一幅图没有,就选删除有的或增加没有的小的cost
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 10 ;
const int inf = 0x7fffffff ;
int map_a[maxn][maxn] ;
int map_b[maxn][maxn] ;
int vis[maxn] ;
int a_b[maxn];
int ans ;
int n , m_a , m_b ;
int I_A , I_B, D_A , D_B ;
void dfs(int num)
{
    if(num == n + 1)
    {
        int sum = 0 ;
        for(int i = 1;i <= n;i++)
          for(int j = 1;j <= n;j++)
          {
              if(map_b[i][j] && !map_a[a_b[i]][a_b[j]])
              sum += min(I_A , D_B) ;
              if(map_a[a_b[i]][a_b[j]] && !map_b[i][j])
              sum += min(I_B , D_A) ;

          }
          ans = min(ans , sum) ;
        return  ;
    }
    for(int i = 1;i <= n;i++)
    {
        if(vis[i])continue ;
        vis[i] = 1;
        a_b[num] = i ;
        dfs(num+1) ;
        vis[i] = 0 ;
    }
}
int main()
{
   //freopen("in.txt" ,"r" ,stdin) ;
    int cas = 0 ;
    while(scanf("%d%d%d" , &n , &m_a , &m_b) &&(n + m_a + m_b))
    {
        memset(vis ,0 , sizeof(vis)) ;
        memset(map_a , 0 , sizeof(map_a)) ;
        memset(map_b , 0 , sizeof(map_b)) ;
        scanf("%d%d%d%d" , &I_A, &I_B , &D_A , &D_B);
        for(int i = 1;i <= m_a;i++)
        {
            int u , v ;
            scanf("%d%d" , &u , &v) ;
            map_a[u + 1][v + 1] = map_a[v+1][u+1] =  1;
        }
        for(int i = 1;i <= m_b; i++)
        {
            int u , v ;
            scanf("%d%d" , &u , &v) ;
            map_b[u+1][v+1]  = map_b[v+1][u+1] =  1;
        }
        ans = inf ;
        dfs(1) ;
        printf("Case #%d: " ,++cas) ;
        printf("%d\n" , ans/2) ;
    }
    return  0 ;
}






















你可能感兴趣的:(暴力枚举,hdu2464)