uva - 140 - Bandwidth(模拟 + 下一个排列 + 图)

来源:互联网 发布:雨果奖 郝景芳 知乎 编辑:程序博客网 时间:2024/06/05 06:41

题目大意:

带宽问题,输入一个图,对这个图的结点进行排列,每一个结点的宽度就是这个结点到它所连接的结点的最大距离。一个排列宽度就是所有结点宽度的最大值。一个图的(最大)最小带宽就是所有排列的中的那个(最大)最小带宽。这个题就是求输入的那个图的最小带宽,和对应的排列。

解题思路:

1、图的输入比较麻烦,用邻接矩阵表示图。然后把结点的名字转换为数字,把数字存在一个数组中,求这个数组中元素的next_permutation()。

2、然后处理这个数组的方法是找数组中两个元素的组合,如果图G[i][j] == 1 表明他们之间有连接,求宽度j-i,和最大比较更新最大。然后循环完后和这个数组的最大和最小比较,更新最小和然后更新结果数组,最后把结果数组再转换成结点的名字就行。


AC代码:


//#define Local#include <iostream>#include <iomanip>#include <string>#include <cstring>#include <cstdio>#include <queue>#include <stack>#include <algorithm>#include <cmath>using namespace std;#define MAX 30 //最多只有8个结点,但是会有26个字母int G[MAX][MAX], vis[MAX], permu[MAX], order[MAX], n, min_len = 100;//用邻接矩阵表示图char s[100];void Transform(){int i = 0, j = 0, u = 0, v = 0, pos = 0;for (i = 0; i < strlen(s); i++){if (':' == s[i+1]){u = s[i] - 'A';vis[u] = 1;pos = i+1;//冒号的位置}else if (i > pos && s[i] >= 'A' && s[i] <= 'Z'){v = s[i] - 'A';G[u][v] = G[v][u] = 1;vis[v] = 1;}}}void Search(){int i = 0, j = 0, max_len = 0;do{max_len = 0;for (i = 0; i < n; i++){for (j = i+1; j < n; j++)//也是在n里找{if (G[permu[i]][permu[j]])//有连接{int cnt = j-i;if (cnt > max_len)max_len = cnt;}}}if (max_len < min_len){min_len = max_len;for (i = 0; i < n; i++)order[i] = permu[i];}}while(next_permutation(permu, permu+n));}int main(){#ifdef Localfreopen("a.in", "r", stdin);freopen("a.out", "w", stdout);#endifint i = 0, j = 0;while (cin >> s){if ('#' == s[0])break;memset(G, 0, sizeof(G));memset(vis, 0, sizeof(vis));memset(permu, 0, sizeof(permu));memset(order, 0, sizeof(order));min_len = 100, n = 0;Transform();for (i = 0, j = 0; i < MAX; i++)if (1 == vis[i])permu[n++] = i;Search();for (i = 0; i < n; i++)cout << char(order[i] + 'A') << ' ';cout << "-> " << min_len << endl;}}


2 0