[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_axios请求后台接口cookie无法传值

    2018年3月7日: 当我们使用http向后台发送请求的时候,需要通过cookie把一些密匙传递给后台做判断授权登陆,当然前提是后台会先把cookie保持到本地. 使用vue开发的时候,会出现这个问题 ...

  2. 11个让你吃惊的linux命令

    我已经用了十年的Linux了,通过今天这篇文章我将向大家展示一系列的命令.工具和技巧,我希望一开始就有人告诉我这些,而不是曾在我成长道路上绊住我. AD: 我已经用了十年的Linux了,通过今天这篇文 ...

  3. 第一章:read/sysread/print/syswrite区别

    use strict; use warnings; #将读入的内容添加到原字符串后面 my $buffer='START:'; , length($buffer)); #my $byts = read ...

  4. python中的binascii模块

    binascii模块拿来干嘛的? 答:进制转换xxoo #!/usr/bin/env python # encoding:utf-8 # by i3ekr import binascii s = &q ...

  5. supervisor 简单使用

    supervisor是一个c/s系统,被用来在类Unix系统中监控进程状态.supervisor使用python开发. 服务端进程为supervisord,主要负责启动自身及其监控的子进程,响应客户端 ...

  6. monkey测试===monkeyrunner测试教程(1)

    1.安装测试环境 jdk 安装与配置 android sdk安装与配置 Python编辑器安装与配置 以上安装请自行百度教程 Monkeyrunner使用方法 http://www.android-d ...

  7. centos_7.1.1503_src_7

    http://vault.centos.org/7.1.1503/os/Source/SPackages/ tex-fonts-hebrew-0.1-21.el7.src.rpm 05-Jul-201 ...

  8. ICTPOS3.0 词性标注集

    Ag 形语素 形容词性语素.形容词代码为a,语素代码g前面置以A. a 形容词 取英语形容词adjective的第1个字母. ad 副形词 直接作状语的形容词.形容词代码a和副词代码d并在一起. an ...

  9. javascript 常用DOM操作整理

    .选取了DOM操作中实用并常用的部分,省略了实用但有明显兼容性的部分2.DOM属性和方法的类型归属可能并不完全准确3.某些一般兼容性和特点做了标识(主要是ie8-9上下) 节点类型 节点类型 节点值 ...

  10. Phoenix批量修改数据

    很简单的一个东西,查了挺久的,浪费了很多的时间 直接用Upsert Into Select就可以了 例:把tables表中cloumn2列等于bbb的都改成aaa Upsert Into Table  ...