UVA140 - Bandwidth

来源:互联网 发布:linux系统命令及shell 编辑:程序博客网 时间:2024/05/21 11:12
Bandwidth
Time limit: 3.000 seconds
Given a graph (V,E) where V is a set of nodes and E is a set of arcs in VxV, and an ordering on the elements in V, then the bandwidth of a node v is defined as the maximum distance in the ordering between v and any node to which it is connected in the graph. The bandwidth of the ordering is then defined as the maximum of the individual bandwidths. For example, consider the following graph:



This can be ordered in many ways, two of which are illustrated below:



For these orderings, the bandwidths of the nodes (in order) are 6, 6, 1, 4, 1, 1, 6, 6 giving an ordering bandwidth of 6, and 5, 3, 1, 4, 3, 5, 1, 4 giving an ordering bandwidth of 5.

Write a program that will find the ordering of a graph that minimises the bandwidth.

Input

Input will consist of a series of graphs. Each graph will appear on a line by itself. The entire file will be terminated by a line consisting of a single #. For each graph, the input will consist of a series of records separated by `;'. Each record will consist of a node name (a single upper case character in the the range `A' to `Z'), followed by a `:' and at least one of its neighbours. The graph will contain no more than 8 nodes.

Output

Output will consist of one line for each graph, listing the ordering of the nodes followed by an arrow (->) and the bandwidth for that ordering. All items must be separated from their neighbours by exactly one space. If more than one ordering produces the same bandwidth, then choose the smallest in lexicographic ordering, that is the one that would appear first in an alphabetic listing.

Sample input

A:FB;B:GC;D:GC;F:AGH;E:HD
#

Sample output

A B C F G D H E -> 3
题目意思是给出n个节点的图,定义节点i的带宽b(i)为i和相邻节点在排列中的最远距离,而所有b(i)的最大值就是这个图的带宽,求出让带宽最小的节点排列.本题可以用递归枚举全排列来计算出每个排列的带宽最大值,然后选取带宽最小的排列输出.在枚举过程中,可以记录下目前的最小带宽,在枚举过程中,如果发现两个节点的距离大于当前最小带宽,则直接跳出当前循环,枚举下个排列(剪枝)!
#include <stdio.h>  #include <string.h>  #include <math.h>  #include <iostream>  #include <algorithm>  using namespace std;  const int Max = 27;    int maps[Max][Max];  int mark[Max];  int num[9], save[9], kind;  char str[500];    void cins(char *a)  {      int len = strlen(a);      int bj;      int flag = 0;      kind = 0;      memset(mark,0,sizeof(mark));      memset(num,0,sizeof(num));      memset(save,0,sizeof(save));      memset(maps,0,sizeof(maps));      for(int i = 0; i < len; i++)      {          if(str[i] >= 'A' && str[i] <= 'Z')///将存在的节点标记为1              mark[str[i] - 'A'] = 1;          if(str[i] == ':')          {              bj = str[i-1] - 'A';              flag = 1;          }          else if(flag && str[i] >= 'A' && str[i] <= 'Z')///前面存在':'号,标记':'前节点与当前节点相邻              maps[str[i] - 'A'][bj] = maps[bj][str[i] - 'A'] = 1;          else if(str[i] == ';')              flag = 0;      }      for(int i = 0; i < 26; i++)///将存在的节点存入数组          if(mark[i])              num[kind++] = i;  }    int main()  {      while(~scanf("%s",str)&&str[0]!='#')      {          int maxs = 0, mem, ans = 10;          cins(str);          do          {              mem = 0;              for(int i = 0; i < kind; i++)              {                  for(int j = i + 1; j < kind; j++)                  {                      if(maps[num[i]][num[j]])///如果两个节点相邻,计算两个之间的带宽,并记录下这个图的最大带宽                          if(abs(i - j) > mem)                              mem = abs(i - j);                  }                  if(mem > ans)///比当前的最优解大,直接"剪枝"掉                      break;              }              if(ans > mem)///找到更优解,则存储当前最优解和当前排列              {                  ans = mem;                  memcpy(save,num,sizeof(num));              }          }while(next_permutation(num,num+kind));///递归枚举全排列          for(int i = 0; i < kind; i++)              printf("%c ",save[i]+'A');          printf("-> %d\n",ans);      }      return 0;  }  


0 0
原创粉丝点击