HDU 3001 Travelling (三进制状态压缩DP+BFS)
2013-08-23 11:13
429 查看
题意:有n个点(n<=10),要求都经过,每个点最多经过两次,求遍历每个点的最小花费。
分析:每个点最多经过两次,则用三进制保存状态,一个好的技巧就是开个pos数组,记录每个状态用三进制表示时,每一位的情况。 枚举每个点为起点,然后每次sum值是不需要清空的,清空了反而造成了诸多重复遍历....................
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#define INF 0x7FFFFFFF
using namespace std;
int p[11];
int pos[60000][11];
int dist[11][11],sum[11][60000];
struct node {
int x,buff;
} q[1111111];
int head,tail,n,m,ans;
void init() {
for(int i=1; i<=10; i++)
for(int j=1; j<=10; j++)
if(i != j) dist[i][j] = INF;
else dist[i][j] = 0;
memset(sum,0,sizeof(sum));
}
void bfs(int v0) {
ans = INF;
// memset(sum,0,sizeof(sum));
head = 0;
tail = 0;
q[head].x = v0;
q[head++].buff = p[v0-1];
while(head != tail) {
node t = q[tail ++];
node tt;
int cnt = 0;
for(int i=0; i<=n; i++) {
if(pos[t.buff][i] >= 1) cnt++;
}
if(cnt == n) {
ans = min(ans,sum[t.x][t.buff]);
}
for(int i=1; i<=n; i++) {
if(t.x == i || dist[t.x][i] == INF) continue;
if(pos[t.buff][i-1] >= 2) continue;
if(sum[t.x][t.buff] + dist[t.x][i] >= ans) continue;
tt.buff = t.buff + p[i-1];
tt.x = i;
if(sum[i][tt.buff] != 0 && sum[i][tt.buff] > sum[t.x][t.buff] + dist[t.x][i]) {
sum[i][tt.buff] = sum[t.x][t.buff] + dist[t.x][i];
q[head++] = tt;
} else if(! sum[i][tt.buff]) {
sum[i][tt.buff] = sum[t.x][t.buff] + dist[t.x][i];
q[head++] = tt;
}
}
}
}
int main() {
int a,b,c;
for(int i=1; i<=11; i++) p[i-1] = pow(3.0,(i-1)*1.0);
for(int i=1; i<=59050; i++) {
int tmp = i,j = 0;
while(tmp) {
pos[i][j++] = tmp % 3;
tmp = tmp / 3;
}
}
while(scanf("%d%d",&n,&m) != EOF) {
init();
for(int i=0; i<m; i++) {
scanf("%d%d%d",&a,&b,&c);
if(c < dist[a][b]) {
dist[a][b] = c;
dist[b][a] = c;
}
}
int minn = INF;
for(int i=1; i<=n; i++) {
bfs(i);
minn = min(minn,ans);
}
if(minn == INF) printf("-1\n");
else printf("%d\n",minn);
}
return 0;
}
分析:每个点最多经过两次,则用三进制保存状态,一个好的技巧就是开个pos数组,记录每个状态用三进制表示时,每一位的情况。 枚举每个点为起点,然后每次sum值是不需要清空的,清空了反而造成了诸多重复遍历....................
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#define INF 0x7FFFFFFF
using namespace std;
int p[11];
int pos[60000][11];
int dist[11][11],sum[11][60000];
struct node {
int x,buff;
} q[1111111];
int head,tail,n,m,ans;
void init() {
for(int i=1; i<=10; i++)
for(int j=1; j<=10; j++)
if(i != j) dist[i][j] = INF;
else dist[i][j] = 0;
memset(sum,0,sizeof(sum));
}
void bfs(int v0) {
ans = INF;
// memset(sum,0,sizeof(sum));
head = 0;
tail = 0;
q[head].x = v0;
q[head++].buff = p[v0-1];
while(head != tail) {
node t = q[tail ++];
node tt;
int cnt = 0;
for(int i=0; i<=n; i++) {
if(pos[t.buff][i] >= 1) cnt++;
}
if(cnt == n) {
ans = min(ans,sum[t.x][t.buff]);
}
for(int i=1; i<=n; i++) {
if(t.x == i || dist[t.x][i] == INF) continue;
if(pos[t.buff][i-1] >= 2) continue;
if(sum[t.x][t.buff] + dist[t.x][i] >= ans) continue;
tt.buff = t.buff + p[i-1];
tt.x = i;
if(sum[i][tt.buff] != 0 && sum[i][tt.buff] > sum[t.x][t.buff] + dist[t.x][i]) {
sum[i][tt.buff] = sum[t.x][t.buff] + dist[t.x][i];
q[head++] = tt;
} else if(! sum[i][tt.buff]) {
sum[i][tt.buff] = sum[t.x][t.buff] + dist[t.x][i];
q[head++] = tt;
}
}
}
}
int main() {
int a,b,c;
for(int i=1; i<=11; i++) p[i-1] = pow(3.0,(i-1)*1.0);
for(int i=1; i<=59050; i++) {
int tmp = i,j = 0;
while(tmp) {
pos[i][j++] = tmp % 3;
tmp = tmp / 3;
}
}
while(scanf("%d%d",&n,&m) != EOF) {
init();
for(int i=0; i<m; i++) {
scanf("%d%d%d",&a,&b,&c);
if(c < dist[a][b]) {
dist[a][b] = c;
dist[b][a] = c;
}
}
int minn = INF;
for(int i=1; i<=n; i++) {
bfs(i);
minn = min(minn,ans);
}
if(minn == INF) printf("-1\n");
else printf("%d\n",minn);
}
return 0;
}
相关文章推荐
- HDU 3001 Travelling (三进制状态压缩 DP)
- HDU 3001 Travelling (三进制状态压缩 DP)
- HDU 3001 Travelling 【状态压缩DP】
- hdu 3001 Travelling//状态压缩DP
- HDU 3001 Travelling(状态压缩DP)
- HDU 3001 Travelling (状态压缩DP)
- HDU 3001 Travelling(状态压缩DP)
- HDU 3001 Travelling(DP状态压缩)
- HDU 3001 Travelling (状态压缩DP +TSP问题)
- HDU 3001 Travelling(状态压缩dp)
- HDU 3001 Travelling (状态压缩DP)
- hdu 3001 Travelling(状态压缩dp)
- HDU 3001 Travelling(状态压缩dp)
- hdu 3001 Travelling (状态压缩dp,三进制!)
- hdu 3001 Travelling (状态压缩dp-----模拟三进制)
- hdu 3001 Travelling 3进制状态压缩dp
- hdu 3001 Travelling (3进制状态dp)
- HDU-3001 Travelling(状态压缩DP,3进制) HQG_AC的博客
- HDU 3001--Travelling(状态压缩+tsp)
- HDU - 3001 Travelling (状态压缩)