POJ 2288 Islands and Bridges(状压dp)
来源:互联网 发布:认字卡片软件 编辑:程序博客网 时间:2024/05/16 15:14
思路:所求的哈密顿路径由三部分组成,一,所有节点的权值之和,二,每条边的权值之和,三,三元环的权值和。设集合S为拜访的点的集合,当向集合S中加入一个点,与上一条边的起点和终点有关。所以令dp[s][i][j]表示集合S通过边(i, j)加入j点之后的最大权值。
那么 dp[s][i][j] = max(dp[s][i][j], dp[p][k][i] + tmp). p表示未加入j点的集合,tmp表示加入j点之后增加的权值,tmp = v[j] + v[i] * v[j], 如果i, j, k三点构成三元环,那么tmp再加上v[i] * v[j] * v[k].
再用一个数组统计路径数。
注意答案会超过int,要用long long.
具体细节见代码
#include<cstdio>#include<set>#include<algorithm>#include<cstring>#include<iostream>#include<map>#include<queue>#include<vector>#include<stack>#include<string>#include<sstream>#include<set>#include<cmath>using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 1e2 + 20;const double EPS = 1e-8;const int mod = 1e8;typedef unsigned long long ull;typedef long long LL;int dx[] = {0, 0, -1, 1, -1, -1, 1, 1};int dy[] = {1, -1, 0, 0, -1, 1, -1, 1};inline int dcmp(double x, double y){if(fabs(x - y) < EPS) return 0; return x > y ? 1 : -1; }int n, m;int g[13][13];LL dp[1 << 13][13][13];int num[1 << 13][13][13];int v[13];int main(){ int T; scanf("%d", &T); while(T--){ scanf("%d%d", &n, &m); for(int i = 0; i < n; ++i){ scanf("%d", &v[i]); } memset(g, 0, sizeof g); memset(num, 0, sizeof num); for(int i = 0; i < m; ++i){ int x, y; scanf("%d%d", &x, &y); g[x - 1][y - 1] = g[y - 1][x - 1] = 1; } memset(dp, -1, sizeof dp); for(int i = 0; i < n; ++i){ for(int j = 0; j < n; ++j){ if(i == j) continue; if(g[i][j] == 0) continue; dp[1 << i | (1 << j)][i][j] = v[i] + v[j] + v[i] * v[j]; num[1 << i | (1 << j)][i][j] = 1; } } LL ans = -1; for(int i = 0; i < (1 << n); ++i){ for(int j = 0; j < n; ++j){ if(i & (1 << j)) continue; for(int k = 0; k < n; ++k){ if(j == k) continue; if(!(i & (1 << k)))continue; if(g[k][j] == 0) continue; for(int l = 0; l < n; ++l){ if(k == l)continue; if(l == j) continue; if(!(i & (1 << l)))continue; if(dp[i][l][k] == -1)continue; LL s = v[j] + v[k] * v[j] + dp[i][l][k]; if(g[j][l]) s += v[k] * v[j] * v[l]; if(dp[i | (1 << j)][k][j] < s){ dp[i | (1 << j)][k][j] = s; num[i | (1 << j)][k][j] = num[i][l][k]; } else if(dp[i | (1 << j)][k][j] == s){ num[i | (1 << j)][k][j] += num[i][l][k]; } } } } } LL cnt = 0; int t = (1 << n) - 1; for(int j = 0; j < n; ++j){ for(int k = 0; k < n; ++k){ if(j == k) continue; ans = max(ans, dp[t][j][k]); } } for(int j = 0; j < n; ++j){ for(int k = 0; k < n; ++k){ if(j == k) continue; if(dp[t][j][k] == ans) cnt += num[t][j][k]; } } cnt /= 2; if(n == 1) ans = v[0], cnt = 1; if(ans != -1) printf("%lld %lld\n", ans, cnt); else printf("0 0\n"); }}/**/
阅读全文
0 0
- Islands and Bridges - POJ 2288 状压dp
- 状压DP poj 2288 Islands and Bridges
- poj 2288 Islands and Bridges(状压dp)
- poj 2288 Islands and Bridges(状压dp)
- poj 2288 Islands and Bridges 状压dp
- poj 2288 Islands and Bridges 状压dp
- POJ 2288 Islands and Bridges(状压dp)
- POJ 2288 Islands and Bridges (状压DP)
- POJ 2288 Islands and Bridges 状压DP
- POJ 2288 Islands and Bridges(状压dp)
- POJ 2288 Islands and Bridges(状压DP)
- POJ 2288 Islands and Bridges(状压dp)
- POJ 2288-Islands and Bridges (状压DP)
- POJ 2288 Islands and Bridges (状压DP)
- poj 2282 Islands and Bridges(状压DP)
- POJ 2288 Islands and Bridges - 状压dp【TSP】
- poj 2288 Islands and Bridges(状压dp,好题)
- poj 2288 Islands and Bridges
- Lua源码解析之二:parser
- 单源最短路Dijkstra算法源码
- Oracle之数据库设计的三大范式
- 高数基础2-序列和极限
- 剑指offer-07:两个栈实现队列
- POJ 2288 Islands and Bridges(状压dp)
- Echarts数据可视化polar极坐标系,开发全解+完美注释
- Git 常用命令总结
- (8)布局display应用:好友菜单
- C/C++ 取整函数ceil(),floor(),round(x)
- CF417A Elimination(完全背包)
- 【PythonDjango后台实例 第一章】Python3.6.1+Pyserial 实现读取STM32蓝牙串口
- StringUtils.equals() 用法
- poj3233(81/600)