• poj 2280 Islands and Bridges 哈密尔顿路 状压dp


    题目链接

    题意

    给定一个(N)个点的无向图,求一条哈密尔顿路径(C_1C_2...C_n),使其(value)最大。

    (value)的计算方式如下:$$egin{aligned}value&=sum_{i=1}{n}C_i&+sum_{i=1}{n-1}C_iC_{i+1}&+sum_{i=1}^{n-2}C_iC_{i+1}*C_{i+2}[(C_i,C_{i+2})is an edge in the graph]end{aligned}$$

    思路

    状态表示及转移等与前两题相类似。

    因为状态和前两步相关,所以用(dp[state][i][j])表示,接连经过(j)点与(i)点到达(state)状态的最大(value)值和对应的路径数目。

    注意答案会爆(int).

    Code

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #define maxn 10010
    #define inf 0x3f3f3f3f
    #define F(i, a, b) for (LL i = (a); i < (b); ++i)
    #define F2(i, a, b) for (LL i = (a); i <= (b); ++i)
    #define dF(i, a, b) for (LL i = (a); i > (b); --i)
    #define dF2(i, a, b) for (LL i = (a); i >= (b); --i)
    using namespace std;
    bool vis[maxn][13][13], dis[13][13];
    typedef long long LL;
    LL v[13], n, m;
    struct node { LL v, w, flag; }dp[maxn][13][13];
    node dfs(LL state, LL p1, LL p2) {
        if (state==(1<<p1)+(1<<p2)) return {v[p1]+v[p2]+v[p1]*v[p2], 1, 1};
        if (vis[state][p1][p2]) return dp[state][p1][p2];
        vis[state][p1][p2] = true;
        LL sta = state - (1<<p1);
        node ans = {0, 0, 0};
        bool flag = false;
        F(i, 0, n) {
            if (i==p1 || i==p2 || !dis[i][p2] || !(state&(1<<i))) continue;
            node nd = dfs(sta, p2, i);
            if (!nd.flag) continue;
            flag = true;
            LL temp = nd.v + (dis[p1][i]?v[p1]*v[p2]*v[i]:0);
            if (temp > ans.v) ans = {temp, nd.w};
            else if (temp == ans.v) ans.w += nd.w;
        }
        if (!flag) return dp[state][p1][p2] = {0, 0, 0};
        else return dp[state][p1][p2] = {ans.v + v[p1] + v[p1]*v[p2], ans.w, 1};
    }
    void work() {
        memset(dis, 0, sizeof dis);
        memset(vis, 0, sizeof vis);
        memset(dp, 0, sizeof dp);
        scanf("%lld%lld", &n, &m);
        F(i, 0, n) scanf("%lld", &v[i]);
        F(i, 0, m) {
            LL u, v;
            scanf("%lld%lld", &u, &v); --u, --v;
            dis[u][v] = dis[v][u] = 1;
        }
        if (n==1) { printf("%lld %lld
    ", v[0], 1); return; }
        node ans = {0, 0, 0};
        F(i, 0, n) {
            F(j, 0, n) {
                if (i==j || !dis[j][i]) continue;
                node temp = dfs((1<<n)-1, i, j);
                if (!temp.flag) continue;
                if (temp.v > ans.v) ans = temp;
                else if (temp.v == ans.v) ans.w += temp.w;
            }
        }
        printf("%lld %lld
    ", ans.v, ans.w>>1);
    }
    int main() {
        LL T;
        scanf("%lld", &T);
        while (T--) work();
        return 0;
    }
    
    
  • 相关阅读:
    python 默认编码( UnicodeDecodeError: 'ascii' codec can't decode)
    python发送各类邮件的主要方法
    python输出htmltestrunner中文乱码如何解决
    Python unittest 官方文档
    Python pip 安装包
    Python easy_insatll 安装包
    linux 解压操作命令
    vim 操作指令2
    vim 操作指令1
    (转)水波纹过渡特效
  • 原文地址:https://www.cnblogs.com/kkkkahlua/p/8451974.html
Copyright © 2020-2023  润新知