您的位置:首页 > 大数据 > 人工智能

A Pair of Graphs(图的构造) HDU 2464

2010-04-05 19:34 399 查看

A Pair of Graphs

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 357    Accepted Submission(s): 184


Problem Description
We say that two graphs are equivalent if and only if a one-to-one correspondence between their nodes can be established and under such a correspondence their edges are exactly the same. Given A and B, two undirected simple graphs with the same number of vertexes, you are to find a series of operations with the minimum cost that will make the two graphs equivalent. An operation may be one of the following two types:
a) Add an arbitrary edge (x, y), provided that (x, y) does not exist before such an operation. Such an operation costs IA and IB on two graphs, respectively.
b) Delete an existing edge (x, y), which costs DA and DB on two graphs,respectively.
 
 

Input
There are multiple test cases in the input file.
Each test case starts with three integers, N, MA and MB, ( 1 ≤ N ≤ 8, 0 ≤ MB ,MA ≤ N*(N-1)/2 ), the total number of vertexes, the number of edges in graph A,and the number of edges in graph B, respectively. Four integers IA, IB, DA, and DB come next, (0 ≤ IA, IB, DA, DB ≤ 32767 ), representing the costs as stated in the problem description. The next MA + MB lines describe the edges in graph A followed by those in graph B. Each line consists of exactly two integers, X and Y ( X ≠ Y , 0 ≤ X,Y < N).
Two successive test cases are separated by a blank line. A case with N = 0, MA = 0,and MB = 0 indicates the end of the input file, and should not be processed by your program.
 
 

Output
Please print the minimum cost in the format as illustrated below.
 
 

Sample Input

1 0 0
1 2 3 7

4 2 3
1 6 5 1
0 1
0 3
0 2
1 2
1 0

0 0 0

 
 

Sample Output

Case #1: 0
Case #2: 1

 
 

Source
2008 Asia Regional Hangzhou
 
 

Recommend
lcy
 

算法分析

这是图的构造问题。首先先构造好图,点与点是否存在通路,两个数组A,B分别拿来保存是否存在通路,接着用深度搜索出所有可能,对,就是穷搜所有可能性,再查看是否满足条件,由于N<=8,最大不过是8!*N*N,不是特别大了,最大经过一些剪枝,讲时间降到了0.29秒。

#include<stdio.h>
#include<string.h>
bool a[9][9],b[9][9],used[9];
int n,ma,mb,ia,ib,da,db,ii,dd,num,list[9];
int min(int a,int b)
{
 if(a>b) return b;
 return a;
}
void dfs(int k) //由于N小于等于8,所以可以使用穷搜,为N!,8!= 40320,很小
{
 int i,j,num2=0;
 if(k==n)
 {
  for(i=0;i<n;i++)
   for(j=0;j<n;j++)
   {
   if(a[list[i]][list[j]]==b[i][j]) continue;
   if(a[list[i]][list[j]])
       num2+=dd;//存在A中边不存在B中边说明要么A减少要么B增加
   else
       num2+=ii;//存在B中边不存在A中边说明要么B减少要么A增加
   }
  if(num>num2) num=num2;
  return;
 }
 else
 for(i=0;i<n;i++)
 if(!used[i])
 {
  list[k]=i;
  used[i]=true;
  dfs(k+1);
  used[i]=false;
 }
}
int main()
{
 int i,j,x,y,count=0;
 freopen("in.txt","r",stdin);
 freopen("out.txt","w",stdout);
 while(scanf("%d%d%d",&n,&ma,&mb)!=EOF)
 {
  scanf("%d%d%d%d",&ia,&ib,&da,&db);
  ii=min(ia,db);//增加A和减少B是等价的,因为我们是以A为研究对象,逐步构成成为B
  dd=min(ib,da);//增加B和减少A是等价的
  if(n==0&&ma==0&&mb==0) break;
  memset(a,false,sizeof(a));
  memset(b,false,sizeof(b));
  memset(used,false,sizeof(used));
  for(i=1;i<=ma;i++)
  {
   scanf("%d%d",&x,&y);
   a[x][y]=a[y][x]=true;
  }
  for(i=1;i<=mb;i++)
  {
   scanf("%d%d",&x,&y);
   b[x][y]=b[y][x]=true;
  }
  num=1<<25;
  dfs(0);
  printf("Case #%d: %d/n",++count,num/2);
 }
 return 0;
}

 

改进版,时间从0.50到了0.29,快了很多

#include<stdio.h>
bool a[9][9],b[9][9],used[9];
int n,ma,mb,ia,ib,da,db,ii,dd,num,list[9];
int min(int a,int b)
{
 if(a>b) return b;
 return a;
}
void dfs(int k) //由于N小于等于8,所以可以使用穷搜,为N!,8!= 40320,很小
{
 int i,j,num2=0;
 if(k==n)
 {
  for(i=0;i<n;i++)
   for(j=i+1;j<n;j++)//这个的改变速度变化很大
   {
   if(a[list[i]][list[j]]==b[i][j]) continue;
   if(a[list[i]][list[j]])
       num2+=dd;//存在A中边不存在B中边说明要么A减少要么B增加
   else
       num2+=ii;//存在B中边不存在A中边说明要么B减少要么A增加
   }
  if(num>num2) num=num2;
  return;
 }
 else
 for(i=0;i<n;i++)
 if(!used[i])
 {
  list[k]=i;
  used[i]=true;
  dfs(k+1);
  used[i]=false;
 }
}
int main()
{
 int i,j,x,y,count=0;
 freopen("in.txt","r",stdin);
 freopen("out.txt","w",stdout);
 while(scanf("%d%d%d",&n,&ma,&mb)!=EOF)
 {
  scanf("%d%d%d%d",&ia,&ib,&da,&db);
  ii=min(ia,db);//增加A和减少B是等价的,因为我们是以A为研究对象,逐步构成成为B
  dd=min(ib,da);//增加B和减少A是等价的
  if(n==0&&ma==0&&mb==0) break;
  for(i=0;i<n;i++)
  { 
    for(j=0;j<n;j++)
    {
    a[i][j]=false;
    b[i][j]=false;
    }
    used[i]=false;
  }
  for(i=1;i<=ma;i++)
  {
   scanf("%d%d",&x,&y);
   a[x][y]=a[y][x]=true;
  }
  for(i=1;i<=mb;i++)
  {
   scanf("%d%d",&x,&y);
   b[x][y]=b[y][x]=true;
  }
  num=1<<25;
  dfs(0);
  printf("Case #%d: %d/n",++count,num);
 }
 return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  pair list graph input ini delete