题意:

给定一个n个结点的图G和一个结点的排列, 定义结点i的带宽b(i)为i和相邻结点在排列中的最远距离, 所有b(i)的最大值就是这个图的带宽, 给定G, 求让带宽最小的结点排列。

给定的图 n <=8, 字母包含A~Z

上图是两种排列, 图1 各个b(i) 为 6 6 1 4 1 1 6 6 最大值为6  图2 b(i)为 5 3 1 4 3 5 1 4 最大值为 5

本图答案应为 A B C F G D H E

b(i)为3  3  3  3  2  3  3  3, 最大值为3.

分析:

首先本题输入格式是那种给出一行,然后比较繁琐的题目, 所以可以考虑先读入一行再进行处理会比边读边处理好一点。

读入后第一要确认的就是这个图包含哪些字母, 因为本题需要全排列并按字典序输出, 所以最好把字母先映射为id, 这里使用了,strchr(const char* , char), 该函数可返回字符串中char第一次出现的位置, 不包含该ch则返回NULL。

并把编号由大到小写到letter中, 那么只需要生成这些id的全排列, 就能知道这些字母的全排列。

第二步是建图, 把输入中有用的信息提炼出来, 那么就可以用邻接矩阵建图了,不使用邻接表是因为本题输入会有重边。

然后就可以dfs生成全排列了, 这里我只用了一个剪枝, 就是搜索到结点u时, 如果u有m个相邻结点,而且有last(m-已经选中的结点)个还没被我前面的递归选中, 那么如果last > 当前最优带宽k, 就可以剪枝。 因为对于结点u而言, 最理想情况是这last个结点紧跟在u后, 这样结点带宽为m, 如果m >= 目前已经找到最优带宽k , 剪枝是合理的。

 #include<bits/stdc++.h>
using namespace std;
char input[];
int id[], letter[], node[], temp[], best_wid[];
int adj[][];
int cnt = ;
int min_wid = 1e5;
bool vis[];
int pos[];
void dfs(int dep){
if(dep == cnt){
int t_wid = -, pp_wid = -;
for(int i = ; i < cnt; i++){
pp_wid = -;
for(int j = ; j < cnt; j++){
if(adj[i][j]){
pp_wid = max(pp_wid, abs(pos[i] - pos[j]) );
}
}
t_wid = max(t_wid, pp_wid);
}
if(t_wid < min_wid){
for(int i = ; i < cnt; i++){
best_wid[i] = temp[i];
}
min_wid = t_wid;
}
}
else{
for(int i = ; i < cnt; i++){
if(!vis[i]){
int last = ;
for(int j = ; j < cnt; j++)
{
if(adj[i][j]){
int ok = ;
for(int k = ; k < dep; k++){
if(temp[k] == j) { ok = ; break;}
}
if(ok) last ++;
}
}
if(last >= min_wid)
continue;
vis[i] = ;
temp[dep] = i;
pos[temp[dep]] = dep;
dfs(dep+);
vis[i] = ;
}
}
}
}
int main()
{
while(scanf("%s", input) && input[] != '#'){
memset(adj,,sizeof(adj));
cnt = , min_wid = 1e5;
for(char a = 'A'; a <= 'Z'; a++){
if(strchr(input, a)){
id[a] = cnt++;
letter[id[a]] = a;
}
}
int len = strlen(input), p=, q=;
while(){
while(p < len && input[p]!= ':')
p++;
if(p == len) break;
while(q < len && input[q]!= ';')
q++;
// p定位: q定位;
for(int i = p+; i < q; i++){
adj[id[input[p-]]][id[input[i]]] = ;
adj[id[input[i]]][id[input[p-]]] = ;
}
p++, q++;
} dfs();
for(int i = ; i < cnt; i++){
printf("%c ", letter[best_wid[i]]);
}
printf("-> %d\n", min_wid);
}
return ;
}

UVA 140 Bandwidth (dfs 剪枝 映射)的更多相关文章

  1. Sticks(UVA - 307)【DFS+剪枝】

    Sticks(UVA - 307) 题目链接 算法 DFS+剪枝 1.这道题题意就是说原本有一些等长的木棍,后来把它们切割,切割成一个个最长为50单位长度的小木棍,现在想让你把它们组合成一个个等长的大 ...

  2. uva 140 bandwidth (好题) ——yhx

     Bandwidth  Given a graph (V,E) where V is a set of nodes and E is a set of arcs in VxV, and an orde ...

  3. UVa 140 Bandwidth【枚举排列】

    题意:给出n个节点的图,和一个节点的排列,定义节点i的带宽b[i]为i和其相邻节点在排列中的最远的距离,所有的b[i]的最大值为这个图的带宽,给一个图,求出带宽最小的节点排列 看的紫书,紫书上说得很详 ...

  4. UVA 140 Bandwidth

    题意: 给出一个n个节点的图G,和一个节点的排列,定义节点i的带宽为i和相邻节点在排列中的最远距离,而所有带宽的最大值就是图的带宽,求让图的带宽最小的排列. 分析: 列出所有可能的排列,记录当前找到的 ...

  5. UVA - 140 Bandwidth(带宽)(全排列)

    题意:给定图,求是带宽最小的结点排列. 分析:结点数最多为8,全排列即可.顶点范围是A~Z. #pragma comment(linker, "/STACK:102400000, 10240 ...

  6. *HDU1455 DFS剪枝

    Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  7. POJ 3009 DFS+剪枝

    POJ3009 DFS+剪枝 原题: Curling 2.0 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16280 Acce ...

  8. poj 1724:ROADS(DFS + 剪枝)

    ROADS Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10777   Accepted: 3961 Descriptio ...

  9. DFS(剪枝) POJ 1011 Sticks

    题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...

随机推荐

  1. DFS(深度) hihoCoder挑战赛14 B 赛车

    题目传送门 题意:中文题面 分析:放官方题解,就是从1为根节点深搜记录节点的深度,选出最大的深度的点,将该到达该点的节点都vis掉,然后再重新计算没有vis的点的深度,找最大的相加就是答案.放张图好理 ...

  2. MFC显示文本文档 分类: MFC 2014-12-30 10:03 457人阅读 评论(1) 收藏

    新建基于对话框的MFC应用程序.资源视图的对话框上添加编辑框(Edit Control)和按钮(Button), 将编辑框属性:Mutiline.Auto HScroll.Auto VScroll设为 ...

  3. Palindromic Subsets 数学 + 线段树

    https://www.hackerrank.com/contests/101hack44/challenges/palindromic-subsets 如果有3个a.2个b.1个c. 每个a看成不同 ...

  4. 工作记录 主要了解EF 列注释DataAnnotations

    遇到一个问题,是子类型必须完全转换为父类型,普通的显示转化.隐式转化.Cast.ConvertAll等方法无效,用Newtonsoft.Json转化才解决 var json = JsonConvert ...

  5. QT入门学习

    第一个QT程序 #include<QApplication> #include<QDialog> #include<QLabel> #include<QTex ...

  6. ubuntu个人初始配置记录

    1.安装vim编辑器 sudo apt-get install vim vim-gnome. vim有vim(vim-basic),vim-tiny,vim-gnome(gvim)等多个版本,安装ub ...

  7. C#中的常量、类型推断和作用域

    一.常量 常量是其值在使用过程中不会发生变化的变量.在声明和初始化变量时,在变量前面家关键字const,就可以把该变量指定为一个常量: const int a=100;//a的值将不可以改变 常量的特 ...

  8. MYSQL 查询方法 统计查询 链接查询 子查询

    mysql表格查询方法: 查询: 1.简单查询 select * from Info --查所有数据select Code,Name from Info --查指定列的数据select Code as ...

  9. C/C++ 数组、字符串、string

    1.定义数组时,数组中元素的个数不能是动态的,不能用变量表示(const变量可以),必须是已知的. 2.引用数组时只能引用数组中某个元素,不能引用整个数组. 3.定义二维数组时,若同时全部初始化,则可 ...

  10. webpac入门

    基于node环境,必须确保node已经安装:node-v,npm-v 基础入门 前身:browserify 缺点:只能转化JS webpack作用:一切都是模块化(js.css图片等),一个模块加载器 ...