例题7-6 带宽(Bandwidth, UVa 140)

欢迎访问我的Uva题解目录哦 https://blog.csdn.net/richenyunqi/article/details/81149109

题目描述

例题7-6 带宽(Bandwidth, UVa 140)题目描述

题意解析

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

算法设计

结点数最多为8,直接暴力求解即可。先用map<char, vector<char>>统计结点及其邻近结点。然后利用next_permutation函数枚举结点的所有排列,统计出每种排列的带宽,即可得出最终结果。

C++代码

#include <bits/stdc++.h>
using namespace std;
map<char, vector<char>> graph;//存储每个结点的邻近结点
string input, ans;
void init() {
    
    //读取每个结点的邻近结点
    graph.clear();
    input += ';';//在字符串后添加一个分号
    for (int i = 0, j = 0; i < input.size(); i = j + 1) {
    
    //遍历输入的字符串
        j = input.find(';', i);//找到分号的位置
        for (char c : input.substr(i + 2, j - i - 2)) {
    
    //添加邻近结点
            graph[input[i]].push_back(c);
            graph[c].push_back(input[i]);
        }
    }
    input = "";
    for (auto& i : graph)//input存储排序后的所有结点编号
        input += i.first;
}
int main() {
    
    
    while (cin >> input && input != "#") {
    
    
        init();
        int width = INT_MAX;//存储最终的最小带宽
        do {
    
    
            unordered_map<char, int> position;//存储当前排列中每个结点的下标
            for (int i = 0; i < input.size(); ++i)
                position[input[i]] = i;
            int w = 0;
            for (auto& i : graph) {
    
    //遍历每个结点
                int wi = 0;
                for (char c : i.second)//遍历每个结点的邻近结点
                    wi = max(wi, abs(position[c] - position[i.first]));
                w = max(w, wi);//更新该结点的带宽
            }
            if (width > w) {
    
    //求解带宽最小的排列
                ans = input;
                width = w;
            }
        } while (next_permutation(input.begin(), input.end()));
        for (char c : ans)
            printf("%c ", c);
        printf("-> %d\n", width);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/richenyunqi/article/details/100695488
7-6
今日推荐