• 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 != '
    ' && *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
    ",k);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    79月知识小结
    将网页上word、pdf、txt文件下载下来,解析成文本内容
    vs 配色方案
    sql时间函数
    关于全角转半角的方法
    多线程与UI操作
    委托调用、子线程程调用、与线程池调用
    算法插入排序
    字符串在某字段里时,如何写搜索的SQL语句
    理解constructor属性
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4628726.html
Copyright © 2020-2023  润新知