UVa140 - Bandwidth
/*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] = '\0'; 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\n", min); } return 0; }