http://acm.hdu.edu.cn/showproblem.php?pid=3001

从任何一个点出发,去到达所有的点,但每个点只能到达2次,使用的经费最小。三进制

Travelling

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

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

从任何一个点出发,去到达所有的点,但每个点只能到达2次,使用的经费最小。三进制。0,1,2.0代表0次,1,1次,2,2次。
dp[i][j]表示i状态到达j城市。
time[i][j]表示i状态到达j城市的次数,就像十进制求余求个位所得。
首先枚举所有的i状态,到达j个城市,在到达下一个城市。
 dp[p][k]=min(dp[p][k],dp[i][j]+dis[j][k]);p是一个城市的状态,i+s[k]所得,s[k]是成倍数所以加起来就是下一个的状态。k是下一个城市。flag去验证是否状态已经是每个城市都到达。
注意要排除重边的情况。
#include<iostream>
#include<cstring>
#include<cstdio>
#define inf 1<<27
using namespace std;
int dis[][],dp[][],s[];
int n,time[][];
void init()
{
int temp,i,j;
s[]=;
for(i=; i<=n+; i++)
s[i]=s[i-]*;
for(i=; i<=s[n+]; i++)
{
temp=i;
for(j=; j<=n; j++)
{
time[i][j]=temp%;//模拟十进制取余求个数的方法。
temp=temp/;
}
}
}
int main()
{
int i,a,b,c,k,m,j,ans,flag;
while(~scanf("%d%d",&n,&m))
{
ans=inf;
for(i=; i<; i++)
{
for(j=; j<; j++)
dp[i][j]=inf;
}
memset(s,,sizeof(s));
memset(time,,sizeof(time));
for(i=; i<=n; i++)
for(j=; j<=n; j++)
{
if(i==j)
dis[i][j]=;
else
dis[i][j]=inf;
}
for(i=; i<=m; i++)
{
scanf("%d%d%d",&a,&b,&c);
dis[a][b]=dis[b][a]=min(dis[a][b],c);//防止有重边。
}
init();
for(i=; i<=n; i++)
dp[s[i]][i]=;//起点位置初始化为0.
for(i=; i<s[n+]; i++)
{
flag=;//各点是否全部已经到了。
for(j=; j<=n; j++)//当前到的这个城市。
{
if(time[i][j]==)//该状态不可能都这个城市。
{
flag=;
continue;
}
for(k=; k<=n; k++)//到下一个城市。
{
if(time[i][k]==||j==k)//如果等于2,就不可以。
continue;
int p=i+s[k];//到达下个城市的状态。
dp[p][k]=min(dp[p][k],dp[i][j]+dis[j][k]);
}
}
if(flag)
{ for(j=; j<=n; j++)
{
ans=min(ans,dp[i][j]);
}
} }
if(ans==inf)
printf("-1\n");
else
printf("%d\n",ans);
}
return ;
}
/*
4 5
1 4 1
1 2 1
1 3 2
4 3 10
2 3 10
*/
 

HDU-3001 Travelling的更多相关文章

  1. HDU 3001 Travelling:TSP(旅行商)【节点最多经过2次】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题意: 有n个城市,m条双向道路,每条道路走一次需要花费路费v.你可以将任意一个城市作为起点出发 ...

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

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

  3. hdu 3001 Travelling (TSP问题 )

    Travelling Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  4. hdu 3001 Travelling(状态压缩 三进制)

    Travelling Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

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

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

  6. HDU 3001 Travelling 3进制状压dp

    题意:10个点,若干条边,边有花费,每个点最多走两次,求走过所有点,花费最少 分析:因为每个点最多走两次,所以联想到3进制,然后枚举状态,就行了(我也是照着网上大神的代码写的) #include &l ...

  7. HDU - 3001 Travelling 状压dp + 三进制 [kuangbin带你飞]专题二

    终于刷完搜索专题了. 题意:给定n个城市,每个城市参观不能超过两次,两个城市之间有道路通过需要花费X,求通过能所有城市的最小花费. 思路:每个城市有三个状态0,1,2,可用三进制存储所有城市的访问状态 ...

  8. Hdu 3001 Travelling 状态DP

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

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

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

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

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

随机推荐

  1. NET 使用HtmlAgilityPack抓取网页数据

    刚刚学习了XPath路径表达式,主要是对XML文档中的节点进行搜索,通过XPath表达式可以对XML文档中的节点位置进行快速定位和访问,html也是也是一种类似于xml的标记语言,但是语法没有那么严谨 ...

  2. Qt源码分析之QObject

    原文:http://blog.csdn.net/oowgsoo/article/details/1529284 我感觉oowgsoo兄弟写的分析相当透彻,赞! 1.试验代码: #include < ...

  3. NSMutableArray 排序

    NSMutableArray *array1=[NSMutableArray arrayWithObjects:@"1",@"3",@"2" ...

  4. mac root用户初始密码设置

    具体方法如下: 1)sudo su切换到root,输入的用户密码是当前用户的密码: 2)切换到root后,执行passwd root,设置root用户密码即可.

  5. PCL—低层次视觉—关键点检测(rangeImage)

    关键点又称为感兴趣的点,是低层次视觉通往高层次视觉的捷径,抑或是高层次感知对低层次处理手段的妥协. ——三维视觉关键点检测 1.关键点,线,面 关键点=特征点: 关键线=边缘: 关键面=foregro ...

  6. shell编程基础(5)---循环指令

    while类型的循环 while类型的循环是不定循环的一种,每一次循环都会验证给出的循环条件,判断是否要进行下一次循环.linux中while循环的写法和c语言中很想,但是条件给出的方式有些区别. 首 ...

  7. Intellij IDEA 构建Spring Web项目 — 用户登录功能

    相关软件: 1.Intellij IDEA14:http://pan.baidu.com/s/1nu16VyD 2.JDK7:http://pan.baidu.com/s/1dEstJ5f 3.Tom ...

  8. Ubuntu链接ubuntu服务器

    以前在windows下用ssh工具putty连接 linux服务器, 很简单,在linux下要连接linux的服务器, 找了下,果然putty在linux中也行1,sudo apt-get insta ...

  9. 25-语言入门-25-n-1位数

    题目地址: http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=96    描述已知w是一个大于10但不大于1000000的无符号整数,若w是n(n ...

  10. BZOJ 3207 花神的嘲讽计划Ⅰ(函数式线段树)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3207 题意:给出一个数列,若干询问.每个询问查询[L,R]区间内是否存在某个长度为K的子 ...