您的位置:首页 > 其它

UVA 140 Brandwidth 带宽 (dfs回溯)

2015-07-07 22:31 363 查看
看到next_permutation好像也能过╮(╯▽╰)╭

这题学习点:

1.建图做映射

2.通过定序枚举保证字典序最小

3.strtok,sscanf,strchr等函数又复习了一遍,尽管程序中没有实际用上

4.剪枝,或者回溯

#include<bits/stdc++.h>
using namespace std;

int G[8][8],deg[8];
bool vG[8][8];//判读连通
int pos[8];
bool vis[8];
int k;
int best[8];
int cnt;
int ID[26];
char rev_ID[8];

void dfs(int d,int width)
{
if(d == cnt){
if(width < k){
k = width;
memcpy(best,pos,sizeof(pos));
}
return;
}
for(int i = 0;i < cnt; i++) if(!vis[i]){//把i放在d位置
pos[d] = i;

//prune 计算i和之前确定位置的结点的最大距离
int m = 0;
for(int j = d-1; j >=0; j--) if(vG[i][pos[j]]) {
m = max(m,d-j);
if(m >= k) continue;//这题数据水了,这里写成return还是能过
}

//prune2 计算u和未确定位置的相邻点的个数,适用于简单图
int ct = 0;
for(int j = 0; j < deg[i]; j++) if(!vis[G[i][j]]) ct++;
if(ct >= k) continue;

vis[i] = 1;
dfs(d+1,max(width,m));
vis[i] = 0;
}
}

int main()
{
// freopen("in.txt","r",stdin);
char buf[100];
const int INF = 0x3fffffff;
while(fgets(buf,100,stdin) && *buf!='#'){
cnt = 0;
memset(vG,0,sizeof(vG));
memset(deg,0,sizeof(deg));
memset(ID,-1,sizeof(ID));
memset(vis,0,sizeof(vis));
bool ap[26] ;
memset(ap,0,sizeof(ap));
for(char *cur = buf; *cur ; cur++) {
int u = *cur - 'A';
if(0<= u && u < 26 ) ap[u] = 1;
}

for(int i = 0; i < 26; i++){
if(ap[i]){
rev_ID[cnt] = i+'A';
ID[i] = cnt++;
}
}

for(char *cur = buf; *cur ; cur++) {
int u = ID[*cur - 'A'];
for(cur+=2 ; *cur != '\n' && *cur != ';' ; cur++) {
int v = ID[*cur - 'A'];
vG[u][v] = vG[v][u] = 1;
}
}

for(int i = 0; i < cnt; i++)
for(int j = 0; j < cnt; j++){
if(vG[i][j]) G[i][deg[i]++] = j;
}
k = INF;
dfs(0,0);
for(int i = 0; i < cnt; i++){
printf("%c ",rev_ID[best[i]]);
}
printf("-> %d\n",k);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: