Travelling

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

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
 
用三进制来进行壮态压缩,这样就可以大大减少状态数,在预处理一下,就可以了,其次,每一个点都要走一次!
#include <iostream>
#include <stdio.h>
using namespace std;
int threenum[11]={1,3,9,27,81,243,729,2187,6561,19683,59049};
#define inf 0x4f4f4f4f
int dp[600000][15],n,m;
int threeevery[600000][15],dis[15][15];
int fmin(int x,int y){if(x<y)return x;return y;}
void makethree()//先预处理,算出所有的值
{
int i,temp,j;
for(i=0;i<threenum[10];i++)//3的11次
{
temp=i;
for(j=0;j<10;j++)
{
threeevery[i][j]=temp%3;
temp=temp/3;
}
} }
void init()
{
int i,j,s,e,val;
for(i=0;i<threenum[n];i++)
{
for(j=0;j<n;j++)
{
dp[i][j]=inf;
}
}
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
dis[i][j]=inf;
}
for(i=0;i<n;i++)
{
dp[threenum[i]][i]=0;//到自已的点初始化为0
} for(i=0;i<m;i++)
{ scanf("%d%d%d",&s,&e,&val);
s--;e--;//全部从0开
             if(val<dis[s][e])
dis[s][e]=dis[e][s]=val;//排除重边取最小值 } }
int makedp()
{
int i,j,k,minx;
bool flag;
minx=inf;
for(i=0;i<threenum[n];i++)//对于每一位都要计算
{
flag=true;//标记是否每一个点都已经经过
for(j=0;j<n;j++)
{
if(threeevery[i][j]==0)//是这个点没有走
flag=false;
if(dp[i][j]==inf)//没有走过
{
continue;
}
for(k=0;k<n;k++)//加入k这个点
{
if((j==k)||threeevery[i][k]>=2||(dis[j][k]==inf))//自已到自已的地方,经过超过两次,不相连通去掉
continue;
dp[i+threenum[k]][k]=fmin(dp[i+threenum[k]][k],dp[i][j]+dis[j][k]);//从j到k
} }
if(flag)//满足条件,对最小值进行更新
{
for(j=0;j<n;j++)
{
minx=fmin(dp[i][j],minx);
}
}
}
if(minx==inf)
{
minx=-1;
} printf("%d\n",minx);
return 1;
}
int main()
{
makethree();
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
makedp();
}
return 0;
}

 

hdu3001 Travelling的更多相关文章

  1. hdu3001Travelling

    参考了别人的代码   https://blog.csdn.net/u010372095/article/details/38474721 深感自己的弱小 这是tsp问题,和基本的tsp问题没什么大的区 ...

随机推荐

  1. Azure SQL 数据库与新的数据库吞吐量单位

    在这一期中,Scott 与 Azure SQL 数据库性能首席项目经理主管 Tobias Ternstrom 一起详细阐释了新的数据库吞吐量单位 (Database Throughput Unit, ...

  2. noip2007提高组题解

    题外话:这一年的noip应该是最受大众关心的,以至于在百度上输入noip第三个关键字就是noip2007.主要是由于这篇文章:http://www.zhihu.com/question/2110727 ...

  3. poj 3469 Dual Core CPU

    题目描述:由于越来越多的计算机配置了双核CPU,TinySoft公司的首席技术官员,SetagLilb,决定升级他们的产品-SWODNIW.SWODNIW包含了N个模块,每个模块必须运行在某个CPU中 ...

  4. 查看buffer cache命中率

    SQL> select name,value from v$sysstat where name in('db block gets','consistent gets','physical r ...

  5. Informatica 9.1常用查询

    select a.mapping_name, a.mapping_id, a.subject_id, a.is_valid, b.pv_precision, c.pv_value, b.pv_defa ...

  6. C# C/S 结构操作Ini系统文件

    Winfrom 开发时,有时会将一些系统某个设置保存到Ini 类型的文件中.下面提供操作Ini 文件的代码: public static class IniFiles { [DllImport(&qu ...

  7. 新浪使用Redis

    新浪微博的工程师们曾经在多个公开场合都讲到过,微博平台当前在使用并维护着可能是世界上最大的Redis集群,其中最大的一个业务,单个业务使用了超过 10T 的内存,这里说的就是微博关系服务. 风起 20 ...

  8. [Everyday Mathematics]20150115

    试计算积分 $$\bex \int_{-\pi}^\pi \frac{\sin nx}{(1+2^x)\sin x}\rd x, \eex$$ 其中 $n$ 是自然数.

  9. fork/join使用示例

    fork/join框架是用多线程的方式实现分治法来解决问题.fork指的是将问题不断地缩小规模,join是指根据子问题的计算结果,得出更高层次的结果. fork/join框架的使用有一定的约束条件: ...

  10. (转载) 数组a[]={3,5,2,4,1,8},要求从a中找出所有“和”等于10的子集

    背包问题.     不过就这道题目本身而言,由于集合a中只要6个元素,而不是成千上万,所以可以使用更直观的办法:     只要你能通过程序给出数组a中元素所组成的集合的所有的子集合(幂集),那么只需在 ...