UVA 140 Brandwidth 带宽 (dfs回溯)

看到next_permutation好像也能过╮(╯▽╰)╭

这题学习点:

1.建图做映射

2.通过定序枚举保证字典序最小

3.strtok,sscanf,strchr等函数又复习了一遍,尽管程序中没有实际用上

4.剪枝,或者回溯

#include<bits/stdc++.h>

using namespace std;



int G[8][8],deg[8];

bool vG[8][8];//判读连通

int pos[8];

bool vis[8];

int k;

int best[8];

int cnt;

int ID[26];

char rev_ID[8];



void dfs(int d,int width)

{

    if(d == cnt){

        if(width < k){

            k = width;

            memcpy(best,pos,sizeof(pos));

        }

        return;

    }

    for(int i = 0;i < cnt; i++) if(!vis[i]){//把i放在d位置

        pos[d] = i;



        //prune 计算i和之前确定位置的结点的最大距离

        int m = 0;

        for(int j = d-1; j >=0; j--) if(vG[i][pos[j]]) {

            m = max(m,d-j);

            if(m >= k) continue;//这题数据水了,这里写成return还是能过

        }



        //prune2 计算u和未确定位置的相邻点的个数,适用于简单图

        int ct = 0;

        for(int j = 0; j < deg[i]; j++) if(!vis[G[i][j]]) ct++;

        if(ct >= k) continue;



        vis[i] = 1;

        dfs(d+1,max(width,m));

        vis[i] = 0;

    }

}





int main()

{

   // freopen("in.txt","r",stdin);

    char buf[100];

    const int INF = 0x3fffffff;

    while(fgets(buf,100,stdin) && *buf!='#'){

        cnt = 0;

        memset(vG,0,sizeof(vG));

        memset(deg,0,sizeof(deg));

        memset(ID,-1,sizeof(ID));

        memset(vis,0,sizeof(vis));

        bool ap[26] ;

        memset(ap,0,sizeof(ap));

        for(char *cur = buf; *cur ; cur++) {

            int u = *cur - 'A';

            if(0<= u && u < 26 ) ap[u] = 1;

        }



        for(int i = 0; i < 26; i++){

            if(ap[i]){

                rev_ID[cnt] = i+'A';

                ID[i] = cnt++;

            }

        }



        for(char *cur = buf; *cur ; cur++) {

            int u = ID[*cur - 'A'];

            for(cur+=2 ; *cur != '\n' && *cur != ';' ; cur++) {

                int v = ID[*cur - 'A'];

                vG[u][v] = vG[v][u] = 1;

            }

        }



        for(int i = 0; i < cnt; i++)

            for(int j = 0; j < cnt; j++){

                if(vG[i][j]) G[i][deg[i]++] = j;

            }

        k = INF;

        dfs(0,0);

        for(int i = 0; i < cnt; i++){

            printf("%c ",rev_ID[best[i]]);

        }

        printf("-> %d\n",k);

    }

    return 0;

}
View Code

 

你可能感兴趣的:(width)