UVA 140 Bandwidth

题目大意:
给一张图的结点连接, 对各个结点进行排列, 排列中的每一个点与存在连接的点的距离的最大值为带宽,求出使带宽最小的排列
题目要我们求出所有排列中,bandwidth最小的那个排列,并输出这个排列和这个bandwidth
解题思路:
利用回溯,一开始设带宽为元素个数,然后一个个元素加入排列,加入元素时与前面已经加入排列并与新加入的元素有连接(即flag2[][] == 1)的元素计算l,如果得到的值l已经大于或者等于目前带宽则直接跳出不用继续扩展
(思路一开始就很清晰,但一些细节需要注意,如在排列前先要排序,遇到带宽相同的排列时用先出现的那个)

#include 
#include 
#include 
#include 
using namespace std;
int flag[27]; //记录是否访问过字母
int flag2[27][27];
int num;
char note[10]; // 记录一共哪些点
char mini[10]; //记录目前最小的排列
int minc; //当前最小的带宽
char now[10]; //当前排列
void dfs(int maxc, int nowc) {
    if(nowc == num) {
        if(maxc < minc) {
            strcpy(mini, now);
            minc = maxc;
        }
    }
    int g = maxc;
    for(int i = 0; i < num; i++) {
        int a = note[i] - 'A';
        maxc = g;
        if(flag[a] == 0) {
            int g = 0;
            for(int j = 0; j < nowc; j++) {
                if(flag2[a][now[j]-'A'] == 1) {
                    int l = nowc - j;
                    if(l >= minc) {
                        g = 1;
                        break;
                    }
                    if(l > maxc)
                        maxc = l;
                }
            }
            if(g == 0) {
                flag[a] = 1;
                now[nowc] = note[i];
                dfs(maxc, nowc+1);
                flag[a] = 0;
            }
        }
    }
}
int main() {
    char p;
    num = 0;
    memset(flag, 0, sizeof(flag));
    memset(flag2, 0, sizeof(flag2));
    p = getchar();
    while(p != '#') {
        getchar();
        char c;
        if(flag[p-'A'] == 0) {
            flag[p-'A'] = 1;
            note[num] = p;
            num++;
        }
        while(1) {
            c = getchar();
            if(c == ';' || c == '\n')
                break;
            flag2[p-'A'][c-'A'] = 1;
            flag2[c-'A'][p-'A'] = 1;
            if(flag[c-'A'] == 0) {
                flag[c-'A'] = 1;
                note[num] = c;
                num++;
            }
        }
        if(c == '\n') {
            sort(note, note+num);
            minc = num;
            memset(flag, 0, sizeof(flag));
            dfs(0, 0);
            for(int i = 0; i < num; i++)
                cout << mini[i] << ' ';
            printf("-> %d\n", minc);
            memset(flag, 0, sizeof(flag));
            memset(flag2, 0, sizeof(flag2));
            num = 0;
        }
        p = getchar();
    }
    return 0;
}

你可能感兴趣的:(刷题,回溯,小白,uva)