zoukankan      html  css  js  c++  java
  • hdu-6149 Valley Numer II 状压DP

    http://acm.hdu.edu.cn/showproblem.php?pid=6149

    把点分为low和high点,high点最多只有15个,所以可以用压位来处理其选取状态。

    枚举low点,然后暴力枚举low点能连接的high点,记忆化搜索一下就好了

    #include <iostream>
    #include <string>
    #include <queue>
    #include <vector>
    #include <cstring>
    using namespace std;
    const int N=35;
    int n,m,k;
    vector<int> g[N];
    int bit[30];
    bool h[N];
    int has[N];
    vector<int> low;
    vector<int> hig;
    int ans;
    int dp[N][40000];
    void dfs(int id,int d,int a)
    {
        if(id==low.size())
        {
            ans=max(ans,a);
            return;
        }
    
        if(a<=dp[id][d])return;
        dp[id][d]=a;
        int li=low[id];
        for(int i=0; i<g[li].size(); i++)
        {
            int pi=g[li][i];
            if(!h[pi])continue;
            int hid1=has[pi];
            if(bit[hid1]&d)continue;
            for(int j=i+1; j<g[li].size(); j++)
            {
                int pj=g[li][j];
                if(!h[pj])continue;
                int hid2=has[pj];
                if(bit[hid2]&d)continue;
                dfs(id+1,d+bit[hid1]+bit[hid2],a+1);
            }
        }
        dfs(id+1,d,a);
    }
    int main()
    {
        cin.sync_with_stdio(false);
        int t;
        bit[0]=1;
        for(int i=1; i<=15; i++)
            bit[i]=bit[i-1]*2;
        //cout<<bit[15]<<endl;32768
        cin>>t;
        while(t--)
        {
            cin>>n>>m>>k;
            for(int i=0;i<n-k;i++)
                for(int j=0;j<(1<<k);j++)
                    dp[i][j]=-1;
            for(int i=1; i<=n; i++)
                g[i].clear();
            low.clear();
            hig.clear();
            ans=0;
            fill(h,h+N,false);
            for(int i=0; i<m; i++)
            {
                int a,b;
                cin>>a>>b;
                g[a].push_back(b);
                g[b].push_back(a);
            }
            for(int i=0; i<k; i++)
            {
                int a;
                cin>>a;
                h[a]=true;
            }
            for(int i=1; i<=n; i++)
            {
                if(!h[i])
                    has[i]=low.size(),low.push_back(i);
                else
                    has[i]=hig.size(),hig.push_back(i);
            }
            for(int i=0;i<low.size();i++)
            {
                int lid=low[i];
                for(int j=g[lid].size()-1;j>=0;j--)
                {
                    if(!h[g[lid][j]])
                        g[lid].erase(g[lid].begin()+j);
                }
            }
            dfs(0,0,0);
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    HDU 4379 水题,大水,但我WA了很多次,做了很久
    HDU 1712分组背包 考试复习安排
    所谓的二维背包Triangular Pastures POJ 1948
    ZOJ 1203 Swordfish Kruskal算法求最小生成树
    POJ 2576 Tug of War二维背包恰好装满.
    O(n*m)复杂度的多重背包coinsPOJ 1742
    拓扑排序POJ 1094
    页面右键下拉表
    gb2312 unicode转换工具
    INPUT读出URL里的变量名称
  • 原文地址:https://www.cnblogs.com/LukeStepByStep/p/8351805.html
Copyright © 2011-2022 走看看