uva-140

暴力搜索

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<sstream>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
int m=9999999999;
vector<int>ch[110],v;
int vis[110]={0},pos[110]={0},ans[110];
void read_graph(string &line){
     memset(ch,0,sizeof(ch));
     memset(vis,0,sizeof(vis));
     int len=line.size();
     int i=0;
     while(i<len){
        vis[line[i]]=1;
        int root=line[i];
        i+=2;
        while(line[i]!=';'&&i<len){
            ch[root].push_back(line[i]);//根节点相邻结点
            vis[line[i]]=1;//记录出现哪些字母
            i++;
        }
        i++;
     }
}
int brand_width(){
int max=0,t;
for(int i=0;i<v.size();i++){
    for(int j=0;j<ch[v[i]].size();j++){
        if(max<(t=(abs(pos[v[i]]-pos[ch[v[i]][j]]))))max=t;
    }
}
return max;
}
void dfs(int cnt){
    int x;
if(cnt==v.size()+1){
    if(m>(x=brand_width())){
        m=x;
        //printf("%d\n",m);
        memcpy(ans,pos,sizeof(pos));
    }
    return;
}
for(int i=0;i<v.size();i++){
    if(pos[v[i]])continue;//记录位置,方便查询
    pos[v[i]]=cnt;
    dfs(cnt+1);
    pos[v[i]]=0;
}
}
int main(){
string line;
while(getline(cin,line)&&line[0]!='#'){
read_graph(line);
for(int i='A';i<='Z';i++)
     if(vis[i])v.push_back(i);
dfs(1);
char ss[100];
for(int i=0;i<v.size();i++)
    ss[ans[v[i]]]=v[i];
for(int i=1;i<=v.size();i++)
    printf("%c ",ss[i]);
printf("-> %d\n",m);
line.clear();
}
return 0;}
时间复杂度近似于n^4;

数组太多,代码长,容易遗漏出错。


剪枝搜索

#include<cstring>
#include<sstream>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<set>
using namespace std;
set<int>s;
const int INF=99999999999;
int G[110][110]={0};
int v[10]={0},ans[10]={0};
int pos[110]={0};
int vis[110]={0};
void read_graph(string &line){
memset(G,0,sizeof(G));
memset(v,0,sizeof(v));
memset(ans,0,sizeof(ans));
memset(pos,0,sizeof(ans));
memset(vis,0,sizeof(vis));
int i=0;
while(i<line.size()){
    int root=line[i];
    s.insert(line[i]);
    i+=2;
    while(line[i]!=';'&&i<line.size()){
        G[root][line[i]]=1;
        G[line[i]][root]=1;
        s.insert(line[i]);
        i++;
    }
    i++;
}
}
int min1=INF;
int update(int p,int x){
    int t;
for(int i=1;i<p;i++)
    if(G[v[i]][v[p]])
        if(x<(t=abs(pos[v[i]]-pos[v[p]])))
          x=t;
return x;
}
void dfs(int cnt,int wid){
if(cnt==s.size()+1){
    if(min1>wid){
        min1=wid;
        memcpy(ans,v,sizeof(v));
    }
    return;
}
set<int>::iterator it;
for(it=s.begin();it!=s.end();it++){
    if(vis[*it])continue;
    vis[*it]=1;
    pos[*it]=cnt;
    v[cnt]=*it;
    int w;
    if((w=update(cnt,wid))<min1)
    dfs(cnt+1,w);
    v[cnt]=0;
    pos[*it]=0;
    vis[*it]=0;
}
}
int main(){
string line;
while(getline(cin,line)&&line[0]!='#'){
    read_graph(line);
    dfs(1,0);
    for(int i=1;i<=s.size();i++)
        printf("%c ",ans[i]);
    printf("-> %d\n",min1);
    line.clear();
    min1=INF;
    s.clear();
}
return 0;}

AC,大量数组,集合,细节容易出错,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值