您的位置:首页 > 其它

UVa--140 BandWidth (DFS)

2016-02-09 20:26 393 查看
传送门

题意:

给出一个有n个顶点的图,结点编号 A ~ Z。给定顶点的一个排列,那么定义结点v的带宽B(v)为v和相邻结点在排列中的最远距离,而所有B(v)的最大值定义为图的带宽。本题所求为给定图G,求出让带宽最小的结点的排列。n <= 8.

题解:

考虑到n <= 8,枚举每个排列再分别计算带宽,然后选取带宽最小的一种排列。需要注意的是,结点编号在A~Z范围内取值,是跳跃性的,所以需要映射到一个连续的整数序列上,方便全排列。

此题建立图略微麻烦。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;

const int maxn = 30;
int graph[maxn][maxn];
int a[maxn], b[maxn];
int n;
map<char, int> mp;

void solve()
{
//结点映射到一个连续整数序列
int i = 0;
for(auto &it : mp){
a[i++] = it.first - 'A';
}

int ans = 1 << 30;
do{
int cur = 0;
//计算结点当前排列下的bandwidth
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < n; ++j)
{
if(graph[a[i]][a[j]]){
cur = max(cur, j - i);
}
}
}
//更新最小bandwidth
if(cur < ans)
{
ans = cur;
for(int i = 0; i < n; ++i)
b[i] = a[i];
}
}while(next_permutation(a, a + n));

for(int i = 0; i < n; ++i)
printf("%c ", 'A' + b[i]);
printf("-> %d\n", ans);
}

int main()
{
string str;
while(cin >> str && str != "#")
{
memset(graph, 0, sizeof(graph));
mp.clear();
//建图
int s = 0, e = 0;
for(int i = 0; i < (int)str.length(); ++i)
{
if(str[i] != ':' && str[i] != ';')
mp[str[i]]++;

e++;
if(str[i] == ';')
{
for(int j = s + 2; j < s + e - 1; ++j)
{
graph[str[s] - 'A'][str[j] - 'A'] = 1;
graph[str[j] - 'A'][str[s] - 'A'] = 1;
}
s += e;
e = 0;
}
}
for(int j = s + 2; j < s + e; ++j)
{
graph[str[s] - 'A'][str[j] - 'A'] = 1;
graph[str[j] - 'A'][str[s] - 'A'] = 1;
}
//图的结点个数
n = mp.size();
solve();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  UVa dfs 搜索 middle