uva 140 Bandwidth

题意:《算法竞赛入门》 196页
思路 : 输入比较特殊,其他正常可以暴力枚举全排列。中间考虑剪枝,在搜索的过程出现的最大带宽比已有还要大就return。但是这题数据太弱了,不剪29ms,剪枝0ms.
由于是全排列问题,也可以直接调用next_permutation()函数简化代码。
dfs无剪枝

#include<bits/stdc++.h>
using namespace std;
int M[26][26],alh[30],node[10],ans[10],cnt,_max,a[10],v[10];
const int inf=0x7fffffff;
string s;
void dfs(int cur)
{
   if(cur==cnt){
       int num=0;
       for(int i=0;i<cnt;i++){
        for(int j=i+1;j<cnt;j++){
            if(M[a[i]][a[j]]&&abs(i-j)>num){
                num=abs(i-j);
            }
        }
       }
       if(num>=_max) return;
       _max=num;
       for(int i=0;i<cnt;i++) ans[i]=a[i];
       return;
    }
     for(int i=0;i<cnt;i++){
      if(!v[i]){
          a[cur]=node[i];
          v[i]=1;
          dfs(cur+1);
          v[i]=0;
      }
   }
}

int main()
{
   while(getline(cin,s)){
      if(s[0]=='#') break;
      int len=s.size(),c,flag=0;
      memset(alh,0,sizeof(alh));
      memset(M,0,sizeof(M));
      for(int i=0;i<len;i++){
         if(s[i]>='A'&&s[i]<='Z'){
              alh[s[i]-'A']=1;
         }
         if(s[i]==':'){
             c=s[i-1]-'A';
             flag=1;
         }
         else if(flag&&s[i]>='A'&&s[i]<='Z'){
            M[c][s[i]-'A']=M[s[i]-'A'][c]=1;
         }
         else if(s[i]==';') flag=0;
      }
      cnt=0;
      for(int i=0;i<26;i++){
          if(alh[i]) node[cnt++]=i;
      }
      _max=inf;
       memset(v,0,sizeof(v));
      dfs(0);

        for(int i = 0; i < cnt; i++)
            printf("%c ", ans[i] + 'A');
        printf("-> %d\n", _max);
   }
}

dfs剪枝

#include<bits/stdc++.h>
using namespace std;
int M[26][26],alh[30],node[10],ans[10],cnt,_max,a[10],v[10];
const int inf=0x7fffffff;
string s;
void dfs(int cur,int cw)
{
   if(cur==cnt){
       _max=cw;
       for(int i=0;i<cnt;i++) ans[i]=a[i];
       return;
    }
     for(int i=0;i<cnt;i++){
      if(!v[i]){
          a[cur]=node[i];
          v[i]=1;
          int t=0;
          for(int j=0;j<cur;j++){
             if(M[node[i]][a[j]]&&abs(cur-j)>t){
                t=abs(cur-j);
             }
          }
          int w=max(cw,t);
          if(w<_max)
              dfs(cur+1,w);
          v[i]=0;
      }
   }
}

int main()
{
   while(getline(cin,s)){
      if(s[0]=='#') break;
      int len=s.size(),c,flag=0;
      memset(alh,0,sizeof(alh));
      memset(M,0,sizeof(M));
      for(int i=0;i<len;i++){
         if(s[i]>='A'&&s[i]<='Z'){
              alh[s[i]-'A']=1;
         }
         if(s[i]==':'){
             c=s[i-1]-'A';
             flag=1;
         }
         else if(flag&&s[i]>='A'&&s[i]<='Z'){
            M[c][s[i]-'A']=M[s[i]-'A'][c]=1;
         }
         else if(s[i]==';') flag=0;
      }
      cnt=0;
      for(int i=0;i<26;i++){
          if(alh[i]) node[cnt++]=i;
      }
      _max=inf;
       memset(v,0,sizeof(v));
      dfs(0,0);
     /* do { int num=0; for(int i = 0; i < cnt; i++) for(int j = i + 1; j < cnt; j++) if(M[node[i]][node[j]]) if(abs(i - j) > num){ num = abs(i - j); //cout<<"num="<<num<<endl; } if(_max > num) { _max = num; memcpy(ans, node, sizeof(node)); } } while(next_permutation(node, node + cnt)); */
        for(int i = 0; i < cnt; i++)
            printf("%c ", ans[i] + 'A');
        printf("-> %d\n", _max);
   }
}

next_permution()无剪枝

#include<bits/stdc++.h>
using namespace std;
int M[26][26],alh[30],node[10],ans[10],cnt,_max,a[10],v[10];
const int inf=0x7fffffff;
string s;
int main()
{
   while(getline(cin,s)){
      if(s[0]=='#') break;
      int len=s.size(),c,flag=0;
      memset(alh,0,sizeof(alh));
      memset(M,0,sizeof(M));
      for(int i=0;i<len;i++){
         if(s[i]>='A'&&s[i]<='Z'){
              alh[s[i]-'A']=1;
         }
         if(s[i]==':'){
             c=s[i-1]-'A';
             flag=1;
         }
         else if(flag&&s[i]>='A'&&s[i]<='Z'){
            M[c][s[i]-'A']=M[s[i]-'A'][c]=1;
         }
         else if(s[i]==';') flag=0;
      }
      cnt=0;
      for(int i=0;i<26;i++){
          if(alh[i]) node[cnt++]=i;
      }
      _max=inf;
      do
        {
            int num=0;
            for(int i = 0; i < cnt; i++)
                for(int j = i + 1; j < cnt; j++)
                    if(M[node[i]][node[j]])
                        if(abs(i - j) > num){
                            num = abs(i - j);
                        }
            if(_max > num)
            {
                _max = num;
                memcpy(ans, node, sizeof(node));
            }
        }
        while(next_permutation(node, node + cnt));

        for(int i = 0; i < cnt; i++)
            printf("%c ", ans[i] + 'A');
        printf("-> %d\n", _max);
   }
}

next_permutation 剪枝

#include<bits/stdc++.h>
using namespace std;
int M[26][26],alh[30],node[10],ans[10],cnt,_max,a[10],v[10];
const int inf=0x7fffffff;
string s;
void dfs(int cur,int cw)
{
   if(cur==cnt){
       _max=cw;
       for(int i=0;i<cnt;i++) ans[i]=a[i];
       return;
    }
     for(int i=0;i<cnt;i++){
      if(!v[i]){
          a[cur]=node[i];
          v[i]=1;
          //dfs剪枝
          int t=0;
          for(int j=0;j<cur;j++){
             if(M[node[i]][a[j]]&&abs(cur-j)>t){
                t=abs(cur-j);
                break;
             }
          }
          int w=max(cw,t);
          if(w<_max)
          dfs(cur+1,w);
          v[i]=0;
      }
   }
}

int main()
{
   while(getline(cin,s)){
      if(s[0]=='#') break;
      int len=s.size(),c,flag=0;
      memset(alh,0,sizeof(alh));
      memset(M,0,sizeof(M));
      for(int i=0;i<len;i++){
         if(s[i]>='A'&&s[i]<='Z'){
              alh[s[i]-'A']=1;
         }
         if(s[i]==':'){
             c=s[i-1]-'A';
             flag=1;
         }
         else if(flag&&s[i]>='A'&&s[i]<='Z'){
            M[c][s[i]-'A']=M[s[i]-'A'][c]=1;
         }
         else if(s[i]==';') flag=0;
      }
      cnt=0;
      for(int i=0;i<26;i++){
          if(alh[i]) node[cnt++]=i;
      }
      _max=inf;
      // memset(v,0,sizeof(v));
      //dfs(0,0);
      do
        {
            int num=0;
            for(int i = 0; i < cnt; i++){
                for(int j = i + 1; j < cnt; j++){
                    if(M[node[i]][node[j]]){
                        if(abs(i - j) > num){
                            num = abs(i - j);
                            //cout<<"num="<<num<<endl;
                        }
                    }
                }
                if(num>_max) break;
            }
            if(_max > num)
            {
                _max = num;
                memcpy(ans, node, sizeof(node));
            }
        }
        while(next_permutation(node, node + cnt));
        for(int i = 0; i < cnt; i++)
            printf("%c ", ans[i] + 'A');
        printf("-> %d\n", _max);
   }
}

你可能感兴趣的:(uva 140 Bandwidth)