UVA-140 Bandwidth

带宽
Sample Input

A:FB;B:GC;D:GC;F:AGH;E:HD
#

Sample Output

A B C F G D H E -> 3

#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int INF = 10000;
int cnt,minb;
int temp[8],ans[8],pos[26];
vector<int> edge[26];//可以使用二维动态数组作为邻接表
void dfs(int cur,int c,int band){//当前答案中的位置,当前字符,当前带宽。
	int i,j,t;
	temp[cur] = c;
	pos[c] = cur;
	for(i = 0;i < edge[c].size(); ++i){
		t = edge[c][i];
		if(pos[t] != -1 && cur - pos[t] > band)
			band = cur - pos[t];
	}
	if(band > minb){//紫书剪枝方式一,方式二这种方法不会实现。。。
		pos[c] = -1;
		return;
	}
	for(i = 0;i < 26; ++i){
		if(pos[i] == -1 && edge[i].size())
			dfs(cur + 1, i, band);
	}
	pos[c] = -1;
	if(cur == cnt - 1){
		if(band < minb){
			for(i = 0;i < cnt; ++i)
				ans[i] = temp[i];
			minb = band;
		}
		pos[c] = -1;
	}
}
int main(){
	string s;
	while((cin >> s) && (s[0] != '#')){
		int i = 0;
		for(int j = 0;j < 26; ++j)
			edge[j].clear(); 
		while(i < s.length()){
			int fir = s[i] - 'A';
			i += 2;
			while(s[i] != ';' && i < s.length()){
				int sec = s[i] - 'A';
				edge[fir].push_back(sec);
				edge[sec].push_back(fir);
				++i;
			} 
			++i;
		}
		memset(pos,-1,sizeof(pos));
		cnt = 0;
		minb = INF;
		for(i = 0;i < 26; ++i){
			if(edge[i].size()){
				++cnt;
				sort(edge[i].begin(),edge[i].end());
			}
		}
		for(i = 0;i < 26; ++i){
			if(edge[i].size()){
				dfs(0,i,0);
			}
		}
		for(i = 0;i < cnt; ++i){
			printf("%c ",ans[i] + 'A');
		}
		printf("-> %d\n",minb);
	}
	return 0;
}

你可能感兴趣的:(算法竞赛入门经典)