码迷,mamicode.com
首页 > 其他好文 > 详细

uva140_dfs(回溯)最优性剪枝

时间:2015-08-20 10:43:16      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:uva   dfs   回溯   剪枝   

题解:
1.原书中已经说明,如果两个节点的带宽 >= 最小带宽,无论如何也不可能比原解更优,应该剪掉。

2.注意此题读入的时候一定要按 字典序 存储,这样计算出的最小值才是符合要求的

3.注意strtok的用法


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
//////////////////////
#include<iostream>
#include<algorithm>
#include<string>
#include <iterator>
#include<sstream>
#include<functional>
#include<numeric>
///////////////////////
#include<vector>
#include<map>
#include <stack>
#include<queue>
#include<set>
#include <bitset>
#include <list>
using namespace std;
#define lch(x)  ((x) << 1)
#define rch(x) ((x)<<1|1)
#define dad(x) ((x)>>1)
#define lowbit(x) ((x)&(-x))
typedef  long long int LL;
const int INF = ~0U>>1;
const double eps = 1e-6;
const long double PI = acos(0.0) * 2.0;
const int N = 10+200;
map<char,int> id;

int mi ,n;
char in[N];
int v[N],ans[N],tmp[N];
bool vis[N],G[N][N];

bool read();
void dfs(int cur , int x);
int ID(char x){return id[x];}

int main()
{
    //ios::sync_with_stdio(false);
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    //freopen("out3.txt", "w", stdout);
#endif
    while(read())
    {
        mi = n; //带宽最大为n
        dfs(0,0);   //dfs(当前位置,上一次算的带宽)
        for(int  i = 0 ; i < n ; i++)       printf("%c ",v[ ans[i] ]+‘A‘);
        printf("-> %d\n",mi);
    }
    return 0;
}


bool read()
{
    gets(in);
    if(in[0]==‘#‘)  return 0;
    char * p,*s=in;
    memset(vis,0,sizeof(vis));
    int l = strlen(in);
    for(int i = 0 ; i< l ; i++) if(isalpha(in[i])) vis[in[i]-‘A‘]=1;  //字典序查找点
    n = 0;          //按字典序把点映射,并收集起来
    for(int i = 0 ; i < 27 ; i++)    if(vis[i])    v[ id[i+‘A‘]=n++ ] = i;

    memset(G,0,sizeof(G));
    while(p = strtok(s,";"))//分割字符串
    {
        for(int i = 2 ; p[i]!=‘\0‘ ; i++)   //转化成邻接矩阵储存,方便查询
            G[ ID(p[0])][ ID(p[i]) ] = G[ ID(p[i])][ ID(p[0])] = 1;
        s = NULL;
    }

    memset(vis,0,sizeof(vis));
    return 1;
}

void dfs(int cur , int x)
{
    if(cur == n)//能运行到这一步的值必定比前一个小
    {                  //更新它
        mi = x;
        memcpy(ans,tmp,sizeof(tmp));
        return ;
    }

    for(int  i = 0 ; i < n ; i++)//回溯生成排列
    {       
        if(!vis[i])
        {
            vis[i] = 1;
            tmp[cur] = i;
            int dk = 0;
            for(int j = 0 ; j < cur ; j++)
            {
                if(G[ i ][ tmp[j] ])
                {
                    dk = cur - j;
                    break;
                }
            }
            dk = max(x,dk);
            if(dk < mi)    dfs(cur+1,dk);   //如果某个节点的带宽比当前最小带宽大,剪掉它
            vis[i] = 0;
        }
    }
}

版权声明:本文为博主原创文章,允许非商业性转载,转载必须注名作者(CSDN tt2767)与本博客链接:http://blog.csdn.net/tt2767。

uva140_dfs(回溯)最优性剪枝

标签:uva   dfs   回溯   剪枝   

原文地址:http://blog.csdn.net/tt2767/article/details/47802691

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!