题目中说明每个城市至少要走一次,至多走2次,因此要用到三进制压缩,然后就是状态转移方程了。

这道题就处理三进制的地方麻烦一点。同时注意,在选择最小长度时,一定是要每一个点都经过至少一次的,即是状态的每一个三进制位均 >=1.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std;
const int inf=1<<30;
struct Edge{
int u,v,c;
int next;
}edge[2000];
int tot,n,m;
int head[15];
int dp[60000][11],tir[60000][12],s[12]; struct Status{
int i,j,c;
Status(){}
Status(int ii,int jj,int cc){i=ii,j=jj,c=cc;}
}que[1800000];
int hed,tail; void addedge(int u,int v,int c){
edge[tot].u=u;
edge[tot].v=v;
edge[tot].c=c;
edge[tot].next=head[u];
head[u]=tot++;
} void init() {
s[0]=1;
for(int i=1; i<=10; i++)
s[i]=s[i-1]*3;
for(int i=0; i<=s[10]; i++){
int t=i;
for(int j=0; j<10; j++){
tir[i][j]=t%3;
t/=3;
}
}
} void slove(){
int u,v;
int ans=inf;
while(hed<tail){
Status tmp=que[hed++];
if(dp[tmp.i][tmp.j]<tmp.c) continue;
bool flag=true;
for(int i=0;i<n;i++){
if(tir[tmp.i][i]==0) {flag=false; break ;}
}
if(flag) ans=min(ans,dp[tmp.i][tmp.j]);
u=tmp.j;
for(int e=head[tmp.j];e!=-1;e=edge[e].next){
v=edge[e].v;
if(v==u||tir[tmp.i][v]==2) continue;
int states=tmp.i+s[v];
if(dp[states][v]>tmp.c+edge[e].c){
dp[states][v]=tmp.c+edge[e].c;
que[tail++]=Status(states,v,dp[states][v]);
}
}
}
printf("%d\n",ans==inf?-1:ans);
} int main(){
int u,v,c;
init();
while(scanf("%d%d",&n,&m)!=EOF){
memset(head,-1,sizeof(head));
tot=0;
for(int i=0;i<m;i++){
scanf("%d%d%d",&u,&v,&c);
u--; v--;
addedge(u,v,c);
addedge(v,u,c);
}
for(int i=0;i<s[n];i++){
for(int j=0;j<n;j++)
dp[i][j]=inf;
}
hed=tail=0;
for(int i=0;i<n;i++){
int st=s[i];
dp[st][i]=0;
que[tail++]=Status(st,i,0);
}
slove();
}
return 0;
}

  

HDU 3001的更多相关文章

  1. HDU 3001 状压DP

    有道状压题用了搜索被队友骂还能不能好好训练了,, hdu 3001 经典的状压dp 大概题意..有n个城市 m个道路  成了一个有向图.n<=10: 然后这个人想去旅行.有个超人开始可以把他扔到 ...

  2. Travelling HDU - 3001

    Travelling HDU - 3001 方法:3进制状态压缩dp(更好的方法是预处理出每个状态数字对应的y数组,然后用刷表,时间复杂度可以少一个n) #include<cstdio> ...

  3. hdu 3001(状压dp, 3进制)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 由于本题中一个点最多能够访问2次,由此可以联想到3进制; visited[i][j]表示在状态i ...

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

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

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

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

  6. hdu 3001(状压dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 思路:这道题类似于TSP问题,只不过题目中说明每个城市至少要走一次,至多走2次,因此要用到三进制 ...

  7. HDU 3001 Traveling(状压DP)

    题目大意:10个点的TSP问题,但是要求每个点最多走两边,不是只可以走一次,所以要用三进制的状态压缩解决这个问题.可以预处理每个状态的第k位是什么. 原代码链接:http://blog.csdn.ne ...

  8. HDU 3001 Travelling 3进制状压dp

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

  9. hdu 3001 Travelling (TSP问题 )

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

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

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

随机推荐

  1. 暴力(python)

    输出由1,2,3,4组成的互不相同且无重复的三位数! #方式一 lst = ['1', '2', '3', '4'] res = [] for i in lst: for j in lst: for ...

  2. Wannafly挑战赛19 A-队列Q

    题目描述 ZZT 创造了一个队列 Q.这个队列包含了 N 个元素,队列中的第 i 个元素用 Qi 表示.Q1 表示队头元素,QN 表示队尾元素.队列中的元素是 N 的一个全排列. ZZT 需要在这个队 ...

  3. Android彻底组件化demo发布

    今年6月份开始,我开始负责对"得到app"的android代码进行组件化拆分,在动手之前我查阅了很多组件化或者模块化的文章,虽然有一些收获,但是很少有文章能够给出一个整体且有效的方 ...

  4. 关于Adaper的相关用法

    使用BaseAdapter的话需要重载四个方法: getCount getItem getItemId getView getView是用来刷新它所在的ListView的.在每一次item从屏幕外滑进 ...

  5. Microsoft SQL Server学习(一)--基本概念

    数据库的分类 关系型数据库 非关系型数据库 数据库的发展 数据都是以文件的形式存储在硬盘上FATFAT32NTFS LinuxEXT 数据库设计流程 文件系统缺陷 数据库的专业术语 数据库引擎服务 E ...

  6. 170925_2 Python socket 创建UDP的服务器端和客户端

    [python版本]3.6 UDP服务器端: from socket import * from time import ctime host = '' port = 21567 buf_size = ...

  7. ARM处理器的寄存器,ARM与Thumb状态,7中运行模式

     ** ARM处理器的寄存器,ARM与Thumb状态,7中运行模式  分类: 嵌入式 ARM处理器工作模式一共有 7 种 : USR  模式    正常用户模式,程序正常执行模式 FIQ模式(Fast ...

  8. codeforces_725C_字符串

    C. Hidden Word time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  9. UpdateData

    UpdateData 类似于C语言的scanf printf函数 管理控件与关联变量之间的数据更新. updatedata(true)把界面输入的数值更新到关联变量中,updatedata(false ...

  10. Oracle query that count connections by minute with start and end times provided

    数据结构类似 SQL> select * from t; B                 E                 N ----------------- ------------ ...