zoukankan      html  css  js  c++  java
  • joj 2630: A Pair of Graphs(同构图的判定)

    http://acm.jlu.edu.cn/joj/showproblem.php?pid=2630&off=2600

    此题是2008年杭州赛区的第一道题,题意其实就是同构图的判定问题。根据数据量,枚举是个可行的办法。代码如下:

    View Code
     1 #include <stdio.h>
     2 #include <memory.h>
     3 #define MAX 1<<30
     4 int ca=1,n,ma,mb,ia,ib,da,db;
     5 int mincost,vis[9],map_v[9],edge_a[9][9],edge_b[9][9];
     6 int min(int a,int b,int c,int d)
     7 {
     8     if(a<=b&&a<=c&&a<=d)return a;
     9     if(b<=a&&b<=c&&b<=d)return b;
    10     if(c<=a&&c<=b&&c<=d)return c;
    11     return d;
    12 }
    13 void dfs(int step)
    14 {
    15     if(mincost==0)return;//可能会提高速度的剪枝
    16     if(step==n)
    17     {
    18         int i,j,dif_ma=ma,dif_mb=mb;
    19         for(i=0;i<n;i++)
    20         {
    21             for(j=i+1;j<n;j++)
    22             {
    23                 if(edge_b[i][j]&&edge_a[map_v[i]][map_v[j]])
    24                 {
    25                     dif_ma--;
    26                     dif_mb--;
    27                 }
    28             }
    29         }
    30         int cur_mincost = min(dif_mb*ia+dif_ma*ib,dif_ma*da+dif_mb*db,dif_ma*da+dif_mb*ia,dif_mb*db+dif_ma*ib);
    31         if(cur_mincost<mincost)mincost = cur_mincost;
    32         return;
    33     }
    34     int j;
    35     for(j=0;j<n;j++)
    36     {
    37         if(!vis[j])
    38         {
    39             vis[j] = 1;
    40             map_v[step] = j;
    41             dfs(step+1);
    42             vis[j] = 0;
    43         }
    44     }
    45 }
    46 int main()
    47 {
    48     int i;
    49     while(scanf("%d%d%d",&n,&ma,&mb),n+ma+mb)
    50     {
    51         memset(edge_a,0,sizeof(edge_a));
    52         memset(edge_b,0,sizeof(edge_b));
    53         scanf("%d%d%d%d",&ia,&ib,&da,&db);
    54         for(i=0;i<ma;i++)
    55         {
    56             int a,b;
    57             scanf("%d%d",&a,&b);
    58             edge_a[a][b]=edge_a[b][a] = 1;
    59 
    60         }
    61         for(i=0;i<mb;i++)
    62         {
    63             int a,b;
    64             scanf("%d%d",&a,&b);
    65             edge_b[a][b]=edge_b[b][a] = 1;
    66         }
    67         mincost = MAX;
    68         memset(vis,0,sizeof(vis));
    69         for(i=0;i<n;i++)map_v[i]=i;
    70         dfs(0);
    71         printf("Case #%d: %d\n",ca++,mincost);
    72     }
    73     return 0;
    74 }

    另外,C++ STL有生成排列数的库函数,效率比一般自己编写的要高,试过之后,速度果然有提高。代码如下:

    View Code
     1 #include <iostream>
     2 #include<algorithm>
     3 using namespace std;
     4 #define MAX 1<<30
     5 int ca=1,n,ma,mb,ia,ib,da,db;
     6 int mincost,map_v[9],edge_a[9][9],edge_b[9][9];
     7 int min(int a,int b,int c,int d)
     8 {
     9     if(a<=b&&a<=c&&a<=d)return a;
    10     if(b<=a&&b<=c&&b<=d)return b;
    11     if(c<=a&&c<=b&&c<=d)return c;
    12     return d;
    13 }
    14 int main()
    15 {
    16     int i;
    17     while(scanf("%d%d%d",&n,&ma,&mb),n+ma+mb)
    18     {
    19         memset(edge_a,0,sizeof(edge_a));
    20         memset(edge_b,0,sizeof(edge_b));
    21         scanf("%d%d%d%d",&ia,&ib,&da,&db);
    22         for(i=0;i<ma;i++)
    23         {
    24             int a,b;
    25             scanf("%d%d",&a,&b);
    26             edge_a[a][b]=edge_a[b][a] = 1;
    27         }
    28         for(i=0;i<mb;i++)
    29         {
    30             int a,b;
    31             scanf("%d%d",&a,&b);
    32             edge_b[a][b]=edge_b[b][a] = 1;
    33         }
    34         mincost = MAX;
    35         int map_v[8]={0,1,2,3,4,5,6,7};
    36         do
    37         {
    38             int i,j,dif_ma=ma,dif_mb=mb;
    39             for(i=0;i<n;i++)
    40             {
    41                 for(j=i+1;j<n;j++)
    42                 {
    43                     if(edge_b[i][j]&&edge_a[map_v[i]][map_v[j]])
    44                     {
    45                         dif_ma--;
    46                         dif_mb--;
    47                     }
    48                 }
    49             }
    50             int cur_mincost = min(dif_mb*ia+dif_ma*ib,dif_ma*da+dif_mb*db,dif_ma*da+dif_mb*ia,dif_mb*db+dif_ma*ib);
    51             if(cur_mincost<mincost)mincost = cur_mincost;
    52         }while (next_permutation(map_v,map_v+n));
    53         printf("Case #%d: %d\n",ca++,mincost);
    54     }
    55 }
  • 相关阅读:
    本周读书的感想
    程序员应知——学习、思考与分享
    用设计版面的思想编写漂亮的代码
    程序员应知——你有几种武器
    《明星DBA成长之路》读后随想
    有些东西不可替代
    DB2连接串&DB2客户端连接服务端
    数据库连接字符串备忘大全
    ASP Blob类型转存为Long Raw类型
    Oracle read_csv
  • 原文地址:https://www.cnblogs.com/laohaizi/p/2789545.html
Copyright © 2011-2022 走看看