Travelling

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

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

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#define M 25
#define INF 0x1f1f1f1f
#define N 65000
using namespace std;
int n,m;
int state[M]={0,1,3,9,27,81,243,729,2187,6561,19683,59049};//state[i]表示第i个点城市状态用3进制表示是多少
int dis[N][M];//dis[i][j]表示i状态j点走过几次
int dp[N][M];//dp[i][j]表示第i个状态最后到达j的最小距离
int g[M][M];//表示两点间的距离
/*
寻找最短路径用了floyd算法的原理,求两个点之前的最短距离,不断寻找中间点来缩小权值;
状态转移:遍历所有的三进制状态,找到上一个状态(第j个城市没去过的或者去过一次的)然后转移到这个状态j位置上加一的状态上,但是能不能转移
要看本次转移是不是会缩短时间
*/
int main()
{
//freopen("in.txt","r",stdin);
for(int i=0;i<59050;i++)
{
int x=i;
for(int j=1;j<=10;j++)//最多有十位
{
dis[i][j]=x%3;
x/=3;
if(x==0)
break;
//cout<<j<<endl;
}
//cout<<i<<endl;
}//初始化第i个状态的j位上的数是几
while(scanf("%d%d",&n,&m)!=EOF)
{
int a,b,c;
memset(g,INF,sizeof g);
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
if(c<g[a][b])
g[a][b]=g[b][a]=c;
}//处理输入
memset(dp,INF,sizeof dp);
int tol=pow(3.0,n);
for(int i=1;i<=n;i++) dp[state[i]][i]=0;//初始化从最后到达i城市最小距离的这个状态转移到i城市需要的最小时间就是0;
int cur=INF;
//下面求最短路径的原理是floyd算法(两个点之间不断寻找中间点来缩小权值)
for(int i=0;i<tol;i++)//枚举所有可能的状态
{
int flag=1;;//用于判断当前状态是不是没走
for(int j=1;j<=n;j++)//枚举你需要找的中间过程的城市
{
if(dis[i][j]==0) flag=0;//判断这个是不是
if(dp[i][j]==INF) continue;
//cout<<"dis[i][j]="<<dis[i][j]<<endl;
for(int k=1;k<=n;k++)//枚举当前当前状态(就是你要转移到的状态)
{
if(j==k) continue;
// cout<<"come in"<<endl;
if(g[j][k]!=INF&&dis[i][k]<2)//从j到k的道路是通的,并且在这个状态中k点经过的次数不到两次
{
int newstate=i+state[k];//新的状态就是走到这个城市,给k点经过的次数加一
dp[newstate][k]=min(dp[newstate][k],dp[i][j]+g[j][k]);
} // cout<<"dp[newstate][k]="<<dp[newstate][k]<<endl;
}
//cout<<j<<endl;
}
if(flag)
for(int j=1;j<=n;j++)
cur=min(dp[i][j],cur);
}
if(cur==INF)//如果取到正无穷就是那么没有联通路所以就不可能走完
puts("-1");
else
printf("%d\n",cur);
}
return 0;
}

  

hdu 3001 Travelling(状态压缩 三进制)的更多相关文章

  1. HDU 3001【状态压缩DP】

    题意: 给n个点m条无向边. 要求每个点最多走两次,要访问所有的点给出要求路线中边的权值总和最小. 思路: 三进制状态压缩DP,0代表走了0次,1,2类推. 第一次弄三进制状态压缩DP,感觉重点是对数 ...

  2. HDU 3001(状态压缩dp)

    状态压缩dp的第一题! 题意:Mr ACMer想要进行一次旅行,他决定访问n座城市.Mr ACMer 可以从任意城市出发,必须访问所有的城市至少一次,并且任何一个城市访问的次数不能超过2次.n座城市间 ...

  3. Hdu 3001 Travelling 状态DP

    题目大意 一次旅游,经过所有城市至少一次,并且任何一座城市访问的次数不能超过两次,求最小费用 每个城市最多访问两次,用状态0,1,2标识访问次数 把城市1~N的状态按照次序连接在一起,就组成了一个三进 ...

  4. hdu 5094 Maze 状态压缩dp+广搜

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092176.html 题目链接:hdu 5094 Maze 状态压缩dp+广搜 使用广度优先 ...

  5. hdu 5724 SG+状态压缩

    Chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  6. HDU 3001 Travelling(状态压缩DP+三进制)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题目大意:有n个城市,m条路,每条路都有一定的花费,可以从任意城市出发,每个城市不能经过两次以上 ...

  7. HDU 3001 Travelling (三进制状态压缩 DP)

    题意:有 n 个city,能够选择任一城市作为起点,每一个城市不能訪问超过2次, 城市之间有权值,问訪问所有n个城市须要的最小权值. 思路:由于每一个城市能够訪问最多两次,所以用三进制表示訪问的状态. ...

  8. hdu 3001 Travelling (三进制)【状压dp】

    <题目链接> 题目大意: 给出n个点和m条边,求经过所有点所需的最小花费,每个点最多经过两次. 解题分析: TSP问题类型,由于此题每个点有三种状态,所以采用三进制状态压缩,0.1.2 分 ...

  9. HDU - 3001 Travelling(三进制状压dp)

    Travelling After coding so many days,Mr Acmer wants to have a good rest.So travelling is the best ch ...

随机推荐

  1. nodejs 初次链接 mongodb 的详细细节

    时间  2016-06-2613:05:16 在前端的学习也有一段时间了,学习了html,css,javascript,jqery,ajax,php,mysql,学习了这些,了解了一些皮毛,也没有什么 ...

  2. 翻译:MariaDB ALTER TABLE语句

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  3. 翻译:MariaDB wait/nowait

    本文为mariadb官方手册:wait/nowait的译文.原文:https://mariadb.com/kb/en/library/wait-and-nowait/ 从MariaDB 10.3.0开 ...

  4. mysql更新某个字符串字段的部分内容

    如果现在需要Mysql更新字段重部分数据,而不是全部数据,应该采用何种方法呢?下面介绍了两种情况下Mysql更新字段中部分数据的方法,供您参考. Mysql更新字段中部分数据第一种情况: update ...

  5. Sublimetext3安装Emmet插件步骤

    看清楚哦~~这是Sublime text 3不是2的版本,两者的安装还是有区别的,下面的方法是我感觉比较简单的,其他的要命令什么的感觉太复杂了,经测试是OK的. 先关闭Sublime text 3: ...

  6. Linux入门(7) 脚本

    1.宣告使用的shell为何 2.注明创建者 编写作用等 3.注释每一个功能函数 执行脚本 1.修改可执行权限 chmod 755 file.sh 2.sh file.sh 可以直接运行脚本 #!/b ...

  7. 分享基于分布式Http长连接框架--架构模型

    我画了个简单的架构图来帮助说明: 其实为发布订阅架构模式. 生产者和消费者我们统一可理解为客户端,消息中间件可认为是服务端. 生产者和消费者做为客户端要跟服务端交互,则先通过代理订阅服务端,订阅成功后 ...

  8. 《算法导论》学习总结 — XX.第22章 图的基本算法

    BFS(广搜): 广搜就是广度优先搜索,根据名字可以知道,是通过广度来遍历图,也就是层次遍历吧. 在这里以及下面的DFS(深搜),都用到了颜色WHITE,GRAY,BLACK,不过作用不同,具体分别再 ...

  9. python --- 网络编程Socket

    网络编程 定义:所为网络编程即是对信息的发送和接收. 主要工作: (1)发送端:将信息以规定的协议组装成数据包. (2)接收端:对收到的数据包解析,以提取所需要的信息. Socket:两个在网络上的程 ...

  10. 微信小程序的跨平台图表库开发

    写在前面 微信小程序出来已经有一段时间了,github上也有很多人开源了很多项目.但是由于微信平台的限制(底层Canvas能力调用为一系列JSBridge封装),图表的制作一直是个比较头疼的问题.当前 ...