带宽(Bandwidth,UVa 140)

原题链接

分析:简单DFS,根据关系图搜索满足题意的解,当遇到带宽大于已知最优解时进行回溯。

PS:开始做题时想当然地把关系数组c声明为c[27][27],WA了两次,真是教训啊。。。。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<string>
#include<map>
#include<cmath>
#include<sstream>
#include<queue>
#include<cctype>
using namespace std;
#define MAX 100001
typedef long long ll;

char str[MAX];
int c['Z'+1]['Z'+1];
vector<char>p;
int vis[27];
int ans,N;
char mid[27],M[27];
void dfs(int cur,int val) {
        if(cur == N) {
                ans = val;
                memcpy(M,mid,sizeof(mid));
                return;
        }
        for(int i=0;i<N;i++)
        if(!vis[i]) {
                vis[i] = 1;
                char u = p[i];
                mid[cur] = u;
		int k = 0;
                for(int v=0;v<cur;v++)
                if(c[u][mid[v]]) {
                        k = max(val,cur - v);
                        break;
                }
		if(k < ans)
			dfs(cur+1,k);
                vis[i] = 0;
        }
}
int main() {
        while(~scanf("%s",str) && str[0] != '#') {
                p.clear();
                memset(c,0,sizeof(c));
                for(int i=0;str[i];i++) {
                        i = strchr(str+i,':') - str;
                        char x = str[i-1];
                        p.push_back(x);
                        while(str[++i] != ';' && str[i]) {
                                c[x][str[i]] = 1;
                                c[str[i]][x] = 1;
                                p.push_back(str[i]);
                        }
                        if(!str[i]) break;
                }
                ans = 50;
                sort(p.begin(), p.end());
                vector<char>::iterator iter = unique(p.begin(), p.end());
                p.erase(iter, p.end());
                N = p.size();
                memset(vis,0,sizeof(vis));
                dfs(0,0);
                for(int i=0;i<N;i++) printf("%c ",M[i]);
                printf("-> %d\n",ans);
        }
        return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值