[hdu3001]Travelling

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7817    Accepted Submission(s):
2553

Problem Description
After coding so many days,Mr Acmer wants to have a good
rest.So travelling is the best choice!He has decided to visit n cities(he
insists on seeing all the cities!And he does not mind which city being his start
station because superman can bring him to any city at first but only once.), and
of course there are m roads here,following a fee as usual.But Mr Acmer gets
bored so easily that he doesn't want to visit a city more than twice!And he is
so mean that he wants to minimize the total fee!He is lazy you see.So he turns
to you for help.
 
Input
There are several test cases,the first line is two
intergers n(1<=n<=10) and m,which means he needs to visit n cities and
there are m roads he can choose,then m lines follow,each line will include three
intergers a,b and c(1<=a,b<=n),means there is a road between a and b and
the cost is of course c.Input to the End Of File.
 
Output
Output the minimum fee that he should pay,or -1 if he
can't find such a route.
 
Sample Input

2 1
1 2 100
3 2
1 2 40
2 3 50
3 3
1 2 3
1 3 4
2 3 10

 
Sample Output

100
90
7

 
Source
 
Recommend
gaojie
 
题目大意:有N个点,M条边,每条边都有权值,每个点不能经过大于两次,问把整个图走完的最小代价。如果不行输出-1。
试题分析:这题不同于codevs上那道3分钟的TSP水题,这回对于次数有限制。
     考虑2进制,我们发现无法表示它的状态了,那么3进制可行么?
     3进制每位代表访问过这个节点的次数。dp[S][j]表示状态为S,现在在j的最小代价。
     那么dp[S][j]=min(dp[S][j],dp[S-tri[j]][k]+e[k][j]);
     tri[i]表示三进制下长度为i的MAX。
     我们可以先预处理出来3进制每个数每位是什么,然后就好做了。
 
代码(为什么就我写的是逆推QAQ):
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std; inline int read(){
int x=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
const int MAXN=100001;
const int INF=0x1f1f1f1f;//这里不知道为什么赋值9999999过不了
const int Max3=59050;
int tri[12] ={0,1,3,9,27,81,243,729,2187,6561,19683,59049};
int N,M;
int ditk[100001][11];
int dp[100001][11];
int e[11][11]; int ans; int main(){
memset(ditk,0,sizeof(ditk));
for(int i=1;i<Max3;i++){
int tmp=0,x=i;
while(x){
ditk[i][++tmp]=x%3;
x/=3;
if(x==0) break;
}
}
while(scanf("%d%d",&N,&M)!=EOF){
ans=INF;
memset(dp,INF,sizeof(dp));
memset(e,INF,sizeof(e));
for(int i=1;i<=M;i++){
int u=read(),v=read(),w=read();
e[u][v]=e[v][u]=min(w,e[v][u]);
}
for(int i=1;i<=N;i++) dp[tri[i]][i]=0;
for(int i=1;i<tri[N+1];i++){
bool k=true;
for(int j=1;j<=N;j++){
if(!dp[i][j]) continue;
if(!ditk[i][j]) continue;
for(int k=1;k<=N;k++){
if(e[k][j]>=INF||ditk[i-tri[j]][j]>=2||k==j||!ditk[i-tri[j]][k]) continue;
dp[i][j]=min(dp[i][j],dp[i-tri[j]][k]+e[k][j]);
}
}
}
for(int i=1;i<tri[N+1];i++){
bool k=true;
for(int j=1;j<=N;j++) if(!ditk[i][j]){
k=false; break;
}
if(k) for(int j=1;j<=N;j++) ans=min(ans,dp[i][j]);
}
if(ans!=INF) printf("%d\n",ans);
else puts("-1");
}
}

又写了一个顺推:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std; inline int read(){
int x=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
const int MAXN=100001;
const int INF=0x1f1f1f1f;
const int Max3=59050;
int tri[12] ={0,1,3,9,27,81,243,729,2187,6561,19683,59049};
int N,M;
int ditk[100001][11];
int dp[100001][11];
int e[11][11]; int main(){
memset(ditk,0,sizeof(ditk));
for(int i=0;i<Max3;i++){
int tmp=0,x=i;
while(x){
ditk[i][++tmp]=x%3;
x/=3;
if(x==0) break;
}
}
while(scanf("%d%d",&N,&M)!=EOF){
int ans=INF;
memset(dp,INF,sizeof(dp));
memset(e,INF,sizeof(e));
for(int i=1;i<=M;i++){
int u=read(),v=read(),w=read();
if(w<e[u][v]) e[u][v]=e[v][u]=w;
}
for(int i=1;i<=N;i++) dp[tri[i]][i]=0;
for(int i=0;i<tri[N+1];i++){
bool flagt=true;
for(int j=1;j<=N;j++){
if(!ditk[i][j]) flagt=false;
if(dp[i][j]==INF) continue;
for(int k=1;k<=N;k++){
if(k==j) continue;
if(e[j][k]>=INF||ditk[i][k]>=2) continue;
dp[i+tri[k]][k]=min(dp[i+tri[k]][k],dp[i][j]+e[j][k]);
}
}
if(flagt){
for(int j=1;j<=N;j++)
ans=min(ans,dp[i][j]);
}
}
if(ans==INF) puts("-1");
else printf("%d\n",ans);
}
}

【状压dp】Travelling的更多相关文章

  1. Travelling(HDU3001+状压dp+三进制+最短路)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题目: 题意:n个城市,m条边,每条边都有一个权值,问你经过所有的城市且每条边通过次数不超过两次 ...

  2. hdu 3001 Travelling 经过所有点(最多两次)的最短路径 三进制状压dp

    题目链接 题意 给定一个\(N\)个点的无向图,求从任意一个点出发,经过所有点的最短路径长度(每个点至多可以经过两次). 思路 状态表示.转移及大体思路 与 poj 3311 Hie with the ...

  3. HDU 3001 Travelling (状压DP,3进制)

    题意: 给出n<=10个点,有m条边的无向图.问:可以从任意点出发,至多经过同一个点2次,遍历所有点的最小费用? 思路: 本题就是要卡你的内存,由于至多可经过同一个点2次,所以只能用3进制来表示 ...

  4. HDU 3001 Travelling ——状压DP

    [题目分析] 赤裸裸的状压DP. 每个点可以经过两次,问经过所有点的最短路径. 然后写了一发四进制(真是好写) 然后就MLE了. 懒得写hash了. 改成三进制,顺利A掉,时间垫底. [代码] #in ...

  5. HDU-4856 Tunnels (BFS+状压DP)

    Problem Description Bob is travelling in Xi’an. He finds many secret tunnels beneath the city. In hi ...

  6. BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3336  Solved: 1936[Submit][ ...

  7. nefu1109 游戏争霸赛(状压dp)

    题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...

  8. poj3311 TSP经典状压dp(Traveling Saleman Problem)

    题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...

  9. [NOIP2016]愤怒的小鸟 D2 T3 状压DP

    [NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...

  10. 【BZOJ2073】[POI2004]PRZ 状压DP

    [BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...

随机推荐

  1. vue-awesome-swipe 基于vue使用的轮播组件 使用(改)

    npm install vue-awesome-swiper --save  //基于vue使用的轮播组件 <template> <swiper :options="swi ...

  2. IE浏览器Bug总结

    每每在网上搜索IE浏览器Bug时,总是骂声一片,特别是前端工程师,每天都要面对,IE浏览器特别是IE6,存在很多Bug,对Web标准的支持也拖后腿,但不可否认,IE浏览器是曾经的霸主,它的贡献也是巨大 ...

  3. Python代码这样写更优雅(转)

    1.变量交换 大部分编程语言中交换两个变量的值时,不得不引入一个临时变量: >>> a = 1>>> b = 2>>> tmp = a>&g ...

  4. perl6中的q/qq/qx/qqx

    q不内插 qq内插 qx不内插 qqx内插

  5. JS中,children和childNodes的不同之处

    <ul id="ul"><li></li><li></li><li><span></spa ...

  6. Microsoft Security Essential: 微软安全软件

    Microsoft Security Essential: 微软安全软件 这个杀毒软件终身免费

  7. 64_l2

    libcec-devel-4.0.2-3.fc26.x86_64.rpm 22-May-2017 22:13 27942 libcephfs-devel-10.2.7-2.fc26.i686.rpm ...

  8. docker基于本地模版导入创建镜像

    /* 因为直接去网站拿会下载的慢,所以直接到网站里,对着此包--〉右键--〉复制链接地址 网站地址:https://openvz.org/Download/template/precreated */ ...

  9. ubuntu 10.04打开错误

    打开ubuntu时,出现的错误如下: Invalid configuration file. File "E:\Ubuntu12.04.vmwarevm\Ubuntu12.04.vmx&qu ...

  10. wifi驱动移植

    目标板:Hi3518 内核版本:linux3.0.8   1.修改makefile #PLATFORM = PC //注释掉 PLATFORM = HI3518 //支持平台 ifeq ($(PLAT ...