poj 2288 (状态压缩+spfa)
来源:互联网 发布:广州拓虹网络 编辑:程序博客网 时间:2024/06/16 06:14
dp[i][j][k] 表示状态为i (二进制第k位为1表示第(k+1)顶点在当前路径里),倒数第二个点为j,最后一个点为k的最大值
之后类似spfa求最常路一样求解,初始把所有单个顶点的状态加入队列里,n==1是特判。
/* * ===================================================================================== * * Filename: 2288.cpp * Version: 1.0 * Created: 2013-08-28 21:53:35 * Revision: none * Compiler: GNU C++ * * Just like you,wait you forever~~ * * ===================================================================================== */#include <set>#include <map>#include <list>#include <queue>#include <stack>#include <cmath>#include <string>#include <cstdio>#include <vector>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define PB push_back#define SIZE(x) (int)x.size()#define clr(x,y) memset(x,y,sizeof(x))#define MP(x,y) make_pair(x,y)#define reads(n) scanf ("%s", n)#define ALL(t) (t).begin(),(t).end()#define FOR(i,n,m) for (int i = n; i <= m; i ++)#define ROF(i,n,m) for (int i = n; i >= m; i --)#define IT iterator#define FF first#define SSsecondtypedef long long ll;typedef unsigned int uint;typedef unsigned long long ull;typedef vector<int> vint;typedef vector<string> vstring;typedef pair<int, int> PII;void RI (int& x){ x = 0; char c = getchar (); while (c == ' '||c == '\n')c = getchar (); bool flag = 1; if (c == '-'){ flag = 0; c = getchar (); } while (c >= '0' && c <= '9'){ x = x * 10 + c - '0'; c = getchar (); } if (!flag)x = -x;}void RII (int& x, int& y){RI (x), RI (y);}void RIII (int& x, int& y, int& z){RI (x), RI (y), RI (z);}/**************************************END define***************************************/const ll mod = 1e9+7;const ll LINF = 1e18;const int INF = 1e9;const double EPS = 1e-8;const int N = 14;pair<ll, ll> dp[1<<(N-1)][N][N];int w[N];bool g[N][N], vis[1<<(N-1)][N][N];void init (){ clr (dp, 0), clr (g, 0), clr (vis, 0);}int main (){ int T; RI (T); while (T --){ init (); int n, m; RII (n, m); FOR (i, 1, n){ RI (w[i]); } while (m --){ int u, v; RII (u, v); g[u][v] = g[v][u] = 1; } queue<pair<PII, int> > q; FOR (i, 1, n){ int val = (1<<(i-1)); dp[val][0][i].FF = w[i]; dp[val][0][i].SS = 1; vis[val][0][i] = 1; q.push (MP (MP (val, 0), i)); } while (SIZE (q)){ pair<PII, int> t = q.front (); q.pop (); int x = t.FF.FF, y = t.FF.SS, z = t.SS; vis[x][y][z] = 0; FOR (i, 1, n){ if (g[z][i]&&(((1<<i-1)&x) == 0)){ ll val = dp[x][y][z].FF + w[i] + w[z] * w[i]; if (g[y][i]) val += w[y]*w[z]*w[i]; int tx = x|(1<<i-1), ty = z, tz = i; if (val > dp[tx][ty][tz].FF){ dp[tx][ty][tz].FF = val; dp[tx][ty][tz].SS = dp[x][y][z].SS; if (!vis[tx][ty][tz]){ q.push (MP (MP (tx, ty), tz)); vis[tx][ty][tz] = 1; } }else if (val == dp[tx][ty][tz].FF){ dp[tx][ty][tz].SS += dp[x][y][z].SS; if (!vis[tx][ty][tz]){ vis[tx][ty][tz] = 1; q.push (MP (MP (tx, ty), tz)); } } } } } int sta = (1<<n)-1; ll maxx = 0, num = 0; FOR (i, 0, n){ FOR (j, 1, n){ if (dp[sta][i][j].FF > maxx){ maxx = dp[sta][i][j].FF; num = dp[sta][i][j].SS; }else if (dp[sta][i][j].FF == maxx){ num += dp[sta][i][j].SS; } } } cout << maxx << " " << num/2 + num%2 << endl; }}
- poj 2288 (状态压缩+spfa)
- poj 2288 状态压缩dp
- POJ 2288 Islands and Bridges(状态压缩)
- Poj 2288 Islands and Bridges 状态压缩
- poj 2288(状态压缩dp + TSP问题)
- POJ 2288(状态压缩dp)
- POJ 2923 状态压缩
- poj 2411 (状态压缩)
- poj 3311 状态压缩
- POJ 3254 状态压缩
- (3254)POJ-状态压缩
- (1185)POJ-状态压缩
- (2817)POJ-状态压缩
- (3311)POJ-状态压缩
- POJ-1143(状态压缩)
- poj 1038 状态压缩
- poj 1185 状态压缩
- poj 2686 状态压缩
- SOA构架
- GO同包内不同文件方法引用问题
- ORA-12838
- php 汉子转unicode编码输出
- 用Dojo实行Confirm模式对话框
- poj 2288 (状态压缩+spfa)
- json数组的简单使用
- EXT.NET PANEL布局
- 大学对自己的一点小要求
- 开源软件测试工具的完整解决方案
- hdu 2821 Pusher (水dfs)
- 【概率论】概率论中的基本概念
- POJ2488 骑士游历 A Knight's Journey 解题报告
- 使用数据库关键字报错