• hdu4085 Peach Blossom Spring 斯坦纳树,状态dp


    (1)集合中元素表示(1<<i), i从0开始

    (2)注意dp[i][ss] = min(dp[i][ss], dp[i][rr | s[i]] + dp[i][(ss ^ rr) | s[i]]);,后面的要 |s[i],保证状态的正确

    (3)INF初始化CLR(dp, 0x3f)

    (4)注意斯坦纳树状态理解,分层松弛的理解

    参考:http://endlesscount.blog.163.com/blog/static/821197872012525113427573/

    //#pragma warning (disable: 4786)
    //#pragma comment (linker, "/STACK:16777216")
    //HEAD
    #include <cstdio>
    #include <ctime>
    #include <cstdlib>
    #include <cstring>
    #include <queue>
    #include <string>
    #include <set>
    #include <stack>
    #include <map>
    #include <cmath>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    //LOOP
    #define FE(i, a, b) for(int i = (a); i <= (b); ++i)
    #define FED(i, b, a) for(int i = (b); i>= (a); --i)
    #define REP(i, N) for(int i = 0; i < (N); ++i)
    #define CLR(A,value) memset(A,value,sizeof(A))
    //INPUT
    #define RI(n) scanf("%d", &n)
    #define RII(n, m) scanf("%d%d", &n, &m)
    #define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
    #define RS(s) scanf("%s", s)
    
    typedef long long LL;
    const int INF = 0x3f3f3f3f;
    const double eps = 1e-10;
    const int MAXN = 1000010;
    
    struct node{
        int to, next, l;
    };
    int tol;
    node adj[2010];
    int head[55];
    void init_adj()
    {
        tol = 0;
        CLR(head, -1);
    }
    void add_edge(int x, int y, int ll)
    {
        adj[tol].to = y;
        adj[tol].l = ll;
        adj[tol].next = head[x];
        head[x] = tol++;
    }
    int dp[55][1 << 11];
    queue<int>q;
    bool inq[55][1 << 11];
    int d[1 << 11];
    int s[55];
    int n, m, k;
    int cnt, ALL;
    
    bool check(int ss)
    {
        int num = 0;
        for (int i = 0; i < cnt; i++)
            if (ss & (1 << i))
                num += i < k ? 1 : -1;
        if (!num) return 1;
        return 0;
    }
    
    void spfa()
    {
        while (!q.empty())
        {
            int u = q.front(); q.pop();
            int ui = u / 10000;
            int uss = u % 10000;
            inq[ui][uss] = 0;
            for (int r = head[ui]; r != -1; r = adj[r].next)
            {
                int vi = adj[r].to;
                int vss = uss | s[vi];
                if (dp[vi][vss] > dp[ui][uss] + adj[r].l)
                {
                    dp[vi][vss] = dp[ui][uss] + adj[r].l;
                    if (vss == uss && !inq[vi][vss]) /// 同层且不再队列中
                    {
                        inq[vi][vss] = 1;
                        q.push(vi * 10000 + vss);
                    }
                }
            }
        }
    }
    
    void solve()
    {
        while (!q.empty()) q.pop();
        CLR(inq, 0);
        FE(ss, 0, ALL)
        {
            FE(i, 1, n)
            {
                for (int rr = ss & (ss - 1); rr; rr = (rr - 1) & ss)///ss
                        dp[i][ss] = min(dp[i][ss], dp[i][rr | s[i]] + dp[i][(ss ^ rr) | s[i]]);
                if (dp[i][ss] < INF)
                    q.push(i * 10000 + ss), inq[i][ss] = 1;
            }
            spfa();
        }
    
        CLR(d, 0x3f);
        FE(ss, 0, ALL) FE(j, 1, n)
            d[ss] = min(d[ss], dp[j][ss]);
    
        REP(ss, ALL + 1)
            for(int rr = ss & (ss - 1); rr; rr = (rr - 1) & ss)
                if (check(rr) && check(ss ^ rr))
                    d[ss] = min(d[ss], d[rr] + d[ss ^ rr]);
    
        if (d[ALL] == INF) printf("No solution
    ");
        else printf("%d
    ", d[ALL]);
    }
    
    
    void init()
    {
        int x, y, l;
        init_adj();
        RIII(n, m, k);
        while (m--)
        {
            RIII(x, y, l);
            add_edge(x, y, l);
            add_edge(y, x, l);
        }
    
        cnt = 2 * k;
        ALL = (1 << cnt) - 1;
    
        CLR(s, 0);
        CLR(dp, 0x3f);
    
        FE(i, 1, k)///集合
        {
            s[i] = 1 << (i - 1);
            dp[i][s[i]] = 0;
            s[n - k + i] = 1 << (k + i - 1);
            dp[n - k + i][s[n - k + i]] = 0;
        }
    }
    
    int main ()
    {
        int T;
        RI(T);
        while (T--)
        {
            init();
            solve();
        }
        return 0;
    }
    


  • 相关阅读:
    支付宝校园一卡通充值服务体验
    商品筛选导航菜单亮点欣赏
    手机QQ v4.2 有感
    因所缺,而所需——互联网应用的开发方向
    浅谈 css3 box盒子模型以及box-flex的使用
    浅谈stylus与sass的对比
    css3 transfrom使用以及其martix(矩阵)属性与其它属性的关系
    js命名空间
    公用的stringUtil工具
    js 实现angylar.js view层和model层双绑定(改变view刷新 model,改变model自动刷新view)
  • 原文地址:https://www.cnblogs.com/pangblog/p/3395439.html
Copyright © 2020-2023  润新知