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;        }}


原创粉丝点击