UVA140 Bandwidth带宽

给出一个图节点数为n(n\leqslant8)让这些节点排序,使得节点的最大带宽要最小,最大带宽就是排列里面与节点相离最远的距离。

有两种方法,第一,因为n比较小就可以枚举全部,然后一个一个的比较,还有一种就是边排列边比较。只要其中两个节点的距离大于目前最大,那么下面的排列可以直接省去。

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn = 10;
int id[256], letter[maxn]; 
int P[maxn], bestP[maxn], pos[maxn];	vector<int>u, v; 		 int ans;
void dfs(int n,int *A,int cur) {
	if (cur == n) {
		for (int i = 0; i < n; i++)pos[A[i]] = i;
		int bandwidth = 0;
		for (int i = 0; i < u.size(); i++) {
			bandwidth = max(bandwidth,abs(pos[u[i]] - pos[v[i]]));
		}
		if (ans > bandwidth) {
			ans = bandwidth;
			for (int i = 0; i < n; i++)bestP[i] = A[i];
		}
	}
	else for (int i = 0; i < n; i++) {
		int ok = 1;
		for (int j = 0; j < cur; j++) {
			if (A[j] == i)ok = 0;
		}
		if (ok) {
			A[cur] = i;
			dfs(n,A,cur + 1);
		}
	}
}
int main() {
	char input[1000];
	while(scanf("%s", input) == 1 && input[0] != '#') {
		int n = 0; memset(pos, 0, sizeof(pos));
		memset(bestP, 0, sizeof(bestP));
		u.clear(); v.clear();
		for (char ch = 'A'; ch < 'Z'; ch++) {
			if (strchr(input, ch) != NULL) {
				id[ch] = n++;
				letter[id[ch]] = ch;
			}
		}

		int len = strlen(input), p = 0, q = 0;
	
		for (;;) {
			while (p < len&&input[p] != ':')p++;
			if (p == len)break;
			while (q < len&&input[q] != ';')q++;
			for (int i = p + 1; i < q; i++) {
				u.push_back(id[input[p - 1]]);
				v.push_back(id[input[i]]);
			}
			p++; q++;
		}

		ans = n; int A[10];
		dfs(n, A, 0);
		for (int i = 0; i < n; i++) printf("%c ", letter[bestP[i]]);
		printf("-> %d\n", ans);
	}
	return 0;
}

下面这种是使用了next_permutation方法

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 10;
int id[256], letter[maxn];
int main() {
	char input[1000];
	while (scanf("%s", input) == 1 && input[0] != '#') {
		// 计算结点个数并给字母编号
		int n = 0;
		for (char ch = 'A'; ch <= 'Z'; ch++)
			if (strchr(input, ch) != NULL) {
				id[ch] = n++;
				letter[id[ch]] = ch;
			}
		// 处理输入
		int len = strlen(input), p = 0, q = 0;
		vector<int> u, v;
		for (;;) {
			while (p < len && input[p] != ':') p++;
			if (p == len) break;
			while (q < len && input[q] != ';') q++;
			for (int i = p + 1; i < q; i++) {
				u.push_back(id[input[p - 1]]);
				v.push_back(id[input[i]]);

			}
			p++; q++;
		}
		// 枚举全排列
		int P[maxn], bestP[maxn], pos[maxn], ans = n;
		for (int i = 0; i < n; i++) P[i] = i;
		do {
			for (int i = 0; i < n; i++) pos[P[i]] = i; // 每个字母的位置
			int bandwidth = 0;
			for (int i = 0; i < u.size(); i++)
				bandwidth = max(bandwidth, abs(pos[u[i]] - pos[v[i]])); // 计算带宽
			if (bandwidth < ans) {
				ans = bandwidth;
			memcpy(bestP, P, sizeof(P));
			}
		} while (next_permutation(P, P + n));
		// 输出
		for (int i = 0; i < n; i++) printf("%c ", letter[bestP[i]]);
		printf("-> %d\n", ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36973725/article/details/83932850