BZOJ1097 旅游景点atr (最短路+状压DP)

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1097分析:见注释。
 1 #include <cstdio>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <functional>
 6 #include <queue>
 7 using namespace std;
 8
 9 #define Node pair<int, int>
10 const int maxk = 20 + 2;
11 const int INF = 1000000000;
12 const int maxm = 200000 + 5;
13 const int maxn = 20000 + 5;
14
15 struct Edge {
16     int to, w, nxt;
17     Edge(int to = 0, int w = 0, int nxt = 0) : to(to), w(w), nxt(nxt) {};
18 };
19
20 int n, m, k, full_set;
21 int tot, head[maxn], dis[maxk][maxk], f[1048576][maxk], depend[maxk], bin[maxk];
22 int d[maxn];
23 bool vis[maxn];
24 Edge e[maxm << 1];
25
26 int read() {
27     int x = 0, f = 1; char ch = getchar();
28     while (ch < ‘0‘ || ch > ‘9‘) { if (ch == ‘-‘) f = -1; ch = getchar(); };
29     while (ch >= ‘0‘ && ch <= ‘9‘) { x = x * 10 + ch - ‘0‘; ch = getchar(); }
30     return x * f;
31 }
32
33 void add_edge(int u, int v, int w) {
34     e[++tot    ].to = v, e[tot].w = w, e[tot].nxt = head[u], head[u] = tot;
35 }
36
37 // 求第(1 ~ k + 1)号节点到其余节点的单源最短路
38 void dijkstra(int x) {
39     priority_queue<Node, vector<Node>, greater<Node> > pq;
40     for (int i = 1; i <= n; i++) d[i] = INF;
41     for (int i = 1; i <= n; i++) vis[i] = 0;
42     d[x] = 0;
43     pq.push(make_pair(0, x));
44     while (!pq.empty()) {
45         int cur = pq.top().second; pq.pop();
46         if (vis[cur]) continue; else vis[cur] = 1;
47         for (int i = head[cur]; i; i = e[i].nxt) {
48             if (d[cur] + e[i].w < d[e[i].to]) {
49                 d[e[i].to] = d[cur] + e[i].w;
50                 pq.push(make_pair(d[e[i].to], e[i].to));
51             }
52         }
53     }
54     for (int i = 1; i <= k + 1; i++) dis[x][i] = d[i];
55     dis[x][k + 2] = d[n];
56 }
57
58 void dp() {
59     for (int old_set = 0; old_set <= full_set; old_set++) // 枚举节点集合
60         for (int cur = 1; cur <= k + 1; cur++) { // 枚举cur为源点
61             if (f[old_set][cur] == -1) continue; // 不存在此状态的表示的路径则返回
62             for (int nxt = 2; nxt <= k + 1; nxt++) {  //枚举nxt为汇点
63                 int new_set = (old_set | bin[nxt - 2]); // 将nxt号节点纳入路径集合
64                 if ((old_set & depend[nxt]) == depend[nxt]) // 判断在nxt号节点停留前是否已经在题目要求的节点停留过
65                     if (f[old_set][cur] + dis[cur][nxt] < f[new_set][nxt] || f[new_set][nxt] == -1) // 更新最短路
66                         f[new_set][nxt] = f[old_set][cur] + dis[cur][nxt];
67             }
68         }
69 }
70
71 int main() {
72     bin[0] = 1; for (int i = 1; i < 22; i++) bin[i] = bin[i - 1] << 1; // bin[i]表示(i - 2)号节点是否纳入路径
73     n = read(); m = read(); k = read(); full_set = bin[k] - 1; // full_set表示2 ~ (k + 1)号节点的全集
74     for (int i = 1, u, v, w; i <= m; i++) { // 建图
75         u = read(); v = read(); w = read();
76         add_edge(u, v, w);
77         add_edge(v, u, w);
78     }
79     for (int i = 1; i <= k + 1; i++) dijkstra(i); // 求出1 ~ (k + 1)号节点到其余节点的单源最短路
80     int x = read();
81     for (int i = 1, u, v; i <= x; i++) {
82         u = read(); v = read();
83         depend[v] += bin[u - 2]; // 表示u号(用二进制的第u - 2位表示)节点在v号节点前停留
84     }
85     memset(f, -1, sizeof(f)); f[0][1] = 0; // 初始化,f[i][j]表示经过i集合(范围2 ~ k + 1)中所有节点*且当前停留在j号节点*的最短路
86     dp(); // 求出走完前(1 ~ k + 1) 号节点最终停留在第i号节点的最短路
87     int ans = INF;
88     for (int i = 1; i <= k + 1; i++)
89         if (f[full_set][i] != -1) ans = min(ans, f[full_set][i] + dis[i][k + 2]); // 找出走完(1 ~ k + 1)号节点停留在i到n的最短路
90     printf("%d", ans); // 输出
91     return 0;
92 }
				
时间: 2024-08-11 01:25:29

BZOJ1097 旅游景点atr (最短路+状压DP)的相关文章

【BZOJ1097】[POI2007]旅游景点atr 最短路+状压DP

[BZOJ1097][POI2007]旅游景点atr Description FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺序不是完全随意的,比如说FGD不希望在刚吃过一顿大餐之后立刻去下一个城市登山,而是希望去另外什么地方喝下午茶.幸运的是,FGD的旅程不是既定的,他可以在某些旅行方案之间进行选择.由于FGD非常讨厌乘车的颠簸,他希望在满足他的要求的情况下,旅行的距离尽量短,这样他就有足够的精力来欣赏风景或者是泡MM了

BZOJ 1097: [POI2007]旅游景点atr( 最短路 + 状压dp )

先最短路预处理, 然后状压就行了 -------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<cctype> #include<queue> using namespace std; #define b(i) (1 <<

HDU 4856 Tunnels (最短路+状压DP)

题意:给你N*N的网格,'.'表示可以走,'#'表示不能走,m条管道,每条管道有起点和终点坐标, Bob每次可以走到相邻的网格花费1s,问Bob走完m条管道要花多少时间:Bob在管道内不计算时间 即计算Bob从管道 i 的出口走到管道 j 的入口的时间Dis(e[i],s[j])的最小和,起点可以任意: 思路:看了题解说是状态压缩DP然后深入理解了下. 首先算出d[e[i]][s[j]]的最短距离,不能到达为-1: dp[i][j] : 表示以 j 为起点状态为 i 的最小值.其中 i 是用十进

【弱校胡策】2016.4.14 (bzoj2164)最短路+状压DP+矩阵乘法+高斯消元+树链剖分+线段树+背包DP

cyyz&qhyz&lwyz&gryz弱校胡策 命题人:cyyz ws_fqk T3暴力写挫了 50+10+0滚粗辣! 奇妙的约会(appointment.cpp/c/pas) [问题描述] DQS和sxb在网上结识后成为了非常好的朋友,并且都有着惊人 的OI水平.在NOI2333的比赛中,两人均拿到了金牌,并保送进入 HU/PKU.于是两人决定在这喜大普奔的时刻进行面基. NOI2333参赛选手众多,所以安排了n个考点,DQS在1号考点, 而sxb在n号考点.由于是举办全国性赛事

HDU 4568 Hunter 最短路+状压DP

题意:给一个n*m的格子,格子中有一些数,如果是正整数则为到此格子的花费,如果为-1表示此格子不可到,现在给k个宝藏的地点(k<=13),求一个人从边界外一点进入整个棋盘,然后拿走所有能拿走的宝藏的最小花费,如果一次不能拿走所有能拿到的或者根本拿不到任何宝藏,输出0. 解法:看到k的范围应该想到状态压缩,将每个格子都看成一个点,再新建两个点,一个表示边界外的起点,用0表示,一个表示边界外的终点,用n*m+1表示,然后相互建边,建有向边,边权为终点格子的花费值,(其实都不用建边,直接跑最短路也行)

YYHS-蜀传之单刀赴会(梦回三国系列T2)(最短路+状压dp)

题目描述 [题目背景] 公元215年,刘备取益州,孙权令诸葛瑾找刘备索要荆州.刘备不答应,孙权极为恼恨,便派吕蒙率军取长沙.零陵.桂阳三郡.长沙.桂阳蜀将当即投降.刘备得知后,亲自从成都赶到公安(今湖北公安),派大将关羽争夺三郡.孙权也随即进驻陆口,派鲁肃屯兵益阳,抵挡关羽.双方剑拔弩张,孙刘联盟面临破裂,在这紧要关头,鲁肃为了维护孙刘联盟,不给曹操可乘之机,决定当面和关羽商谈."肃邀羽相见,各驻兵马百步上,但诸将军单刀俱会".双方经过会谈,缓和了紧张局势.随后,孙权与刘备商定平分荆州

POJ 3311-Hie with the Pie(最短路+状压DP)

题目链接:点击打开链接 题意:大致就是邮递员要从0号 送快件,一共有n个地方,要求从0开始走完所有的节点在回到0的最短路径.先用Floyd跑出来最短路,然后就是一个裸TSP问题了 TSP:顾名思义,旅行商问题,就是从起点出发遍历n个城市在回到起点的最短路径,在n比较小的情况下状压是个比较好的办法,二进制0代表没访问该城市,反之亦然.所以一共有 2^n-1种状态, 设 dp[s][i] 代表当前状态为s 当前所在城市节点为i dp[s][i]=min(dp[s][i] ,dp[s'][j]+dis

【BZOJ-1097】旅游景点atr SPFA + 状压DP

1097: [POI2007]旅游景点atr Time Limit: 30 Sec  Memory Limit: 357 MBSubmit: 1531  Solved: 352[Submit][Status][Discuss] Description FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺序不是完全随意的,比如说FGD不希望在刚吃过一顿大餐之后立刻去下一个城市登山,而是希望去另外什么地方喝下午茶.幸运的是,FGD

【bzoj1097】[POI2007]旅游景点atr 状压dp+堆优化Dijkstra

题目描述 FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺序不是完全随意的,比如说FGD不希望在刚吃过一顿大餐之后立刻去下一个城市登山,而是希望去另外什么地方喝下午茶.幸运的是,FGD的旅程不是既定的,他可以在某些旅行方案之间进行选择.由于FGD非常讨厌乘车的颠簸,他希望在满足他的要求的情况下,旅行的距离尽量短,这样他就有足够的精力来欣赏风景或者是泡MM了^_^.整个城市交通网络包含N个城市以及城市与城市之间的双向道路M条