UVa140

/*UVa 140 140 - Bandwidth
---数据量比较小,可以直接用next_permutation来枚举全排列,依次计算每一个排序的b(i),求出最小即可
---在枚举时,注意到在计算某一个排列的带宽过程中,如果发现某两个节点的带宽大于当前总的最小带宽k
---则可以直接剪掉。
*/
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string.h>
#include<fstream>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 26;
const int maxsize = 10000;

int G[maxn][maxn];
char ans[maxn];
char vertex[maxsize];   
char str[maxsize];  //一开始把数组开小了,一直WA,原来串还可以比较长

int main(){
	//ofstream fout("a.txt");
	int u, v,cnt,N,x;
	while (scanf("%s", str)&&strcmp(str,"#")){
		int n = strlen(str);
		memset(G, -1, sizeof(G));
		cnt = 0;
		for (int i = 0; i < n; i++){
			vertex[cnt++] = str[i];
			u = str[i] - 'A';
			i += 2;
			while (i<n&&str[i] != ';'){
				vertex[cnt++] = str[i];
				v = str[i] - 'A';
				G[u][v] = G[v][u] = 0;  //有边
				i++;
			}
		}
		sort(vertex, vertex + cnt);
		N = unique(vertex, vertex + cnt) - vertex;
		vertex[N] = '';
		int min = INF;
		do{
			x = 0;          //x代表当前排列下的带宽
			for (int i = 0; i < N; i++){  //计算每个顶点带宽值
				u = vertex[i] - 'A';
				for (int j = i + 1; j < N; j++){
					v = vertex[j] - 'A';
					if (G[u][v] == 0){ //如果有边
						x = max(x, j - i);
						if (x >= min)break; //剪枝
					}
				}
				if (x>=min)break; //剪枝
			}
			if (x < min){
				min = x;
				memcpy(ans, vertex, strlen(vertex));  //内存拷贝函数
			}
		} while (next_permutation(vertex, vertex + N));
		for (int i = 0; i < N; i++)printf("%c ", ans[i]);
		printf("-> %d
", min);
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/td15980891505/p/5822694.html