BestCoder Round #52 (div.2) HDU 5418 Victor and World (DP+状态压缩)
2015-08-22 21:55
429 查看
【题目链接】:click here~~
【题目大意】:
问题描述
输入描述
输出描述
输入样例
输出样例
【思路】:
我们首先需要预处理出任意两个国家之间的最短距离,因为数据范围很小,所以直接用Floyd就行了。之后,我们用f[S][i]表示访问国家的情况为S,当前最后访问的一个国家是i所需要的最小总油量,其中,S的二进制表示记录了访问国家的情况,S在二进制表示下的第i位(不管是从左往右还是从右往左都可以)如果是1则表示第i个国家被访问过了,否则表示第i个国家没有被访问过,那么f[S|(1<<i)][i]=min(f[S][j]+mat[i][j])(mat[i][j]:表示城市i,j的最短路径),其中i和j满足S&(1<<j)=1且S&(1<<i)=0。最开始时,除了f[1][1]是0,其他情况都是无穷大,之后先枚举S,再枚举i,那么最终的答案就是min(f[(1<<n)-1][i]+f[i][1]),其中i\in∈[2,n]。总复杂度为O(n^3+n^2*2^n)O(n3+n2∗2n)。
代码:
【题目大意】:
问题描述
经过多年的努力,Victor终于考到了飞行驾照。为了庆祝这件事,他决定给自己买一架飞机然后环游世界。他会驾驶一架飞机沿着规定的航线飞行。在地球上一共有nn个国家,编号从11到nn,各个国家之间通过mm条双向航线连接,第ii条航线连接第u_iui个国家与第v_ivi个国家,通过这条航线需要消耗w_iwi升油,且从11号国家可以直接或间接到达22到nn中任意一个国家。 Victor一开始位于11号国家,他想知道从11号国家出发,经过各个国家至少一次并最后回到11号国家消耗的总油量的最小值是多少。
输入描述
第一行包含一个整数TT,表示测试数据的组数。 每组测试数据的第一行有两个整数nn和mm,表示国家的个数和航线的条数。 接下来mm行,每行三个整数u_iui, v_ivi, w_iwi,描述一条航线。 1\leq T\leq 201≤T≤20。 1\leq n\leq 161≤n≤16。 1\leq m\leq 1000001≤m≤100000。 1\leq w_i\leq 1001≤wi≤100。 1\leq u_i, v_i \leq n1≤ui,vi≤n。
输出描述
每组测试数据输出一行一个整数,即消耗的总油量的最小值。
输入样例
1 3 2 1 2 2 1 3 3
输出样例
10
【思路】:
我们首先需要预处理出任意两个国家之间的最短距离,因为数据范围很小,所以直接用Floyd就行了。之后,我们用f[S][i]表示访问国家的情况为S,当前最后访问的一个国家是i所需要的最小总油量,其中,S的二进制表示记录了访问国家的情况,S在二进制表示下的第i位(不管是从左往右还是从右往左都可以)如果是1则表示第i个国家被访问过了,否则表示第i个国家没有被访问过,那么f[S|(1<<i)][i]=min(f[S][j]+mat[i][j])(mat[i][j]:表示城市i,j的最短路径),其中i和j满足S&(1<<j)=1且S&(1<<i)=0。最开始时,除了f[1][1]是0,其他情况都是无穷大,之后先枚举S,再枚举i,那么最终的答案就是min(f[(1<<n)-1][i]+f[i][1]),其中i\in∈[2,n]。总复杂度为O(n^3+n^2*2^n)O(n3+n2∗2n)。
代码:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <fstream>
#include <cstring>
#include <climits>
#include <deque>
#include <cmath>
#include <queue>
#include <stack>
#include <ctime>
#include <list>
#include <map>
#include <set>
#include <utility>
#include <sstream>
#include <complex>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <functional>
#include <algorithm>
using namespace std;
#define rep(i,j,k) for(int i=(int)j;i<(int)k;++i)
#define per(i,j,k) for(int i=(int)j;i>(int)k;--i)
#define lowbit(a) a&-a
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define mem(a,b) memset(a,b,sizeof(a))
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const int N=1e5+100;
const double eps = 1e-15;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int, int> pir;
int mat[100][100];
int dp[(1<<16)+10][20];
int dir4[4][2]= {{1,0},{0,1},{-1,0},{0,-1}};
int dir8[8][2]= {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
int movv[5][2]= {{1,0},{0,1},{0,0},{-1,0},{0,-1}};
inline LL read()
{
int c=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
return c*f;
}
int main(){
int t;t=read();
while (t--){
mem(dp,inf);mem(mat,inf);
int u, v, w, n, m;
n=read();m=read();
for(int i = 1; i <= m; ++i){
u=read();v=read();w=read();--u;--v;
mat[u][v] = Min(mat[u][v], w);
mat[v][u] = Min(mat[v][u], w);
}
for (int i = 0; i < n; ++i){
mat[i][i] = 0;
}
for (int k = 0; k < n; ++k){// floyd
for (int i = 0; i < n; ++i){
for (int j = 0; j < n; ++j){
mat[i][j] = Min(mat[i][j], mat[i][k] + mat[k][j]);
}
}
}
dp[0][0] = 0;
for (int i = 0; i < (1 << n); ++i){
for (int j = 0; j < n; ++j){
if (dp[i][j] != inf){
for (int k = 0; k < n; ++k){
dp[i | (1 << k)][k] = Min(dp[i | (1 << k)][k], dp[i][j] + mat[j][k]);
}
}
}
}
printf("%d\n", dp[(1 << n) - 1][0]);
}
return 0;
}
/*
1 3 2 1 2 2 1 3 3
*/
相关文章推荐
- 使用资源组快速浏览跨region资源
- 人生需要拆穿(读书笔记)
- Android消息机制分析
- 使用Lock来实现生产者和消费者问题
- Android GUI之Window、WindowManager
- 黑马程序员11模拟实现银行业务调度系统
- poj185 炮兵阵地 状压DP
- HDU 3513 Human or Pig
- 【英语】Bingo口语笔记(55) - work系列
- 快学Scala习题解答—第十二章 高阶函数
- 策略(strategy)模式
- IOS UI UIScrollView+UIPageControl组合使用
- 内部类详解
- 策略(strategy)模式
- spring启动流程
- android application 收集所有avtivity
- java高级特性和核心优化gc
- 学渣级别springmvc初探
- 为什么有些网站前面不加 WWW?
- 我常用的 16 个 Sublime Text 快捷键