zoukankan      html  css  js  c++  java
  • 有向图 同构

    转载自:http://fghtech.blogbus.com/logs/56854632.html

    http://162.105.81.212/JudgeOnline/problem?id=2040  

    题意给定两个有向图,找出其同构的对应点,并输出其对应的序列。。。

    这题是给你两种语言的几个短语,让你翻译,求出各个单词的对应关系。

    这里可以把单词抽象成点,把短语抽象成线,然后就是一个有向图了。于是问题就转化成了求两个同构图中各点的对应关系。由于题目规模比较小,所以可以用深度优先搜索。

    这里有个特殊情况就是,当一个节点的出度和入度在这张图中唯一,那么在另一张图中也一定有唯一一个节点有相应的出度和入度,于是这个不用搜索就可以确定,可以预处理。如上第一个图的节点3和第二个图的节点0的出度和入度是对应的。

    搜索条件是:对于第一张图pos这个节点,而且pos到k有一条边,k这个点在图中已经找到了匹配点,但是在第二张图中点i与该匹配点没有边相连,则pos的对应点一定不会是i

    1 #pragma warning (disable : 4786)
    2 #include <iostream>
    3 #include <map>
    4 #include <string>
    5  using namespace std;
    6  struct Node
    7 {
    8 string str;
    9 int match; //正数代表匹配节点编号,-1代表还没匹配
    10 int outDegree, inDegree;
    11 };
    12 bool line1[25][25]; //如果w[i] w[k]是一个短语,则line1[i][k] = true,代表一条从i指向k的边
    13 bool line2[25][25];
    14 Node node1[25], node2[25];
    15 int n, n1, n2;
    16 map< string, int > sim1, sim2; //字符串到其下标的映射
    17 void Init() //读入,将字符串下标化,并建立好图
    18 {
    19 int i;
    20 string str1, str2;
    21 memset(line1, false, sizeof(line1));
    22 memset(line2, false, sizeof(line2));
    23 n1 = n2 = 0;
    24 sim1.clear();
    25 sim2.clear();
    26 for(i=0; i<25; i++)
    27 {
    28 node1[i].outDegree = node1[i].inDegree = node2[i].outDegree = node2[i].inDegree = 0;
    29 node1[i].match = node2[i].match = -1;
    30 }
    31 for(i=0; i<n; i++)
    32 {
    33 cin >> str1 >> str2;
    34 if(sim1.find(str1) == sim1.end())
    35 {
    36 sim1[str1] = n1;
    37 node1[n1++].str = str1;
    38 }
    39 if(sim1.find(str2) == sim1.end())
    40 {
    41 sim1[str2] = n1;
    42 node1[n1++].str = str2;
    43 }
    44 line1[sim1[str1]][sim1[str2]] = true;
    45 node1[sim1[str1]].outDegree++;
    46 node1[sim1[str2]].inDegree++;
    47 }
    48 for(i=0; i<n; i++)
    49 {
    50 cin >> str1 >> str2;
    51 if(sim2.find(str1) == sim2.end())
    52 {
    53 sim2[str1] = n2;
    54 node2[n2++].str = str1;
    55 }
    56 if(sim2.find(str2) == sim2.end())
    57 {
    58 sim2[str2] = n2;
    59 node2[n2++].str = str2;
    60 }
    61 line2[sim2[str1]][sim2[str2]] = true;
    62 node2[sim2[str1]].outDegree++;
    63 node2[sim2[str2]].inDegree++;
    64 }
    65 }
    66 void InitCompute() //先根据特殊情况确定部分对应关系。
    67 {
    68 int i, k, samecnt;
    69 for(i=0; i<n1; i++)
    70 {
    71 samecnt = 0;
    72 for(k=0; k<n2; k++)
    73 {
    74 if(node2[k].outDegree == node1[i].outDegree && node2[k].inDegree == node1[i].inDegree)
    75 {
    76 samecnt++;
    77 node1[i].match = k;
    78 }
    79 }
    80 if(samecnt > 1)
    81 node1[i].match = -1;
    82 else
    83 node2[node1[i].match].match = i;
    84 }
    85 }
    86 bool DFS(int pos) //对第一张图深度优先搜索
    87 {
    88 if(pos < 0) //搜索到解了
    89 return true;
    90 else if(node1[pos].match != -1) //这个节点已经匹配
    91 return DFS(pos-1);
    92 else
    93 {
    94 int i, k, l;
    95 for(i=0; i<n2; i++)
    96 {
    97 if(node2[i].match == -1 && node2[i].outDegree == node1[pos].outDegree && node2[i].inDegree == node1[pos].inDegree)
    98 {
    99 for(k=0; k<n1; k++)
    100 {
    101 //对于第一张图pos这个节点,而且pos到k有一条边,k这个点在图2中已经找到了匹配点,但是在第二张图中点i与该
    102 //匹配点没有边相连,则pos的对应点一定不会是i
    103 if(k != pos && line1[pos][k] && node1[k].match != -1 && !line2[i][node1[k].match])
    104 break;
    105 }
    106 for(l=0; l<n1; l++)
    107 {
    108 if(l != pos && line1[l][pos] && node1[l].match != -1 && !line2[node1[l].match][i])
    109 break;
    110 }
    111 if(k == n1 && l == n1) //检查到没有冲突就匹配,继续搜
    112 {
    113 node1[pos].match = i;
    114 node2[i].match = pos;
    115 if(DFS(pos-1))
    116 return true;
    117 //搜不到解就回溯
    118 node1[pos].match = node2[i].match = -1;
    119 }
    120 }
    121 }
    122 return false;
    123 }
    124 }
    125 void Print()
    126 {
    127 map< string, int >::iterator iter, end = sim1.end();
    128 for(iter=sim1.begin(); iter!=end; iter++)
    129 {
    130 cout << iter->first << '/' << node2[node1[iter->second].match].str << endl;
    131 }
    132 }
    133 int main()
    134 {
    135 // freopen("data.txt", "r", stdin);
    136 for(scanf("%d", &n); ; )
    137 {
    138 Init();
    139 InitCompute();
    140 DFS(n1-1);
    141 Print();
    142 scanf("%d", &n);
    143 if(n == 0)
    144 break;
    145 else
    146 printf("\n");
    147 }
    148 return 0;
    149 }
  • 相关阅读:
    mysql5.7 linux安装参考
    谈谈微服务中的 API 网关(API Gateway)
    十大Intellij IDEA快捷键
    SqoopFlume、Flume、HDFS之间比较
    PostgreSQL-存储过程(一)基础篇
    spark调优篇-oom 优化(汇总)
    spark调优篇-数据倾斜(汇总)
    spark调优篇-Spark ON Yarn 内存管理(汇总)
    spark异常篇-OutOfMemory:GC overhead limit exceeded
    spark异常篇-Removing executor 5 with no recent heartbeats: 120504 ms exceeds timeout 120000 ms 可能的解决方案
  • 原文地址:https://www.cnblogs.com/freewater/p/2097784.html
Copyright © 2011-2022 走看看