首页 > 其他分享 >CF1741G(状态压缩,DP)

CF1741G(状态压缩,DP)

时间:2022-10-16 20:37:29浏览次数:76  
标签:int 压缩 cin CF1741G vector include rep DP define

CF1741G(状态压缩,DP)

Problem - G - Codeforces

题意

给一个无向连通图,有 \(f\) 个朋友在节点1,每个人的家在 \(h_i\) ,其中有 \(k(k \le 6)\)个朋友没有车,有车的朋友可以开车载任意数量的没车且家在有车朋友的回家的最短路上的没车朋友回家。问最后无法被开车送回的朋友的最小数量。

思路

\(k\) 的数量很小,可以考虑将朋友送到每个节点的状态压入 \(k\) 个bit位中。然后问题就变成对有车朋友最大化可行方案的bit位中1的个数。这个做一个可行性dp。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<bitset>
#include<queue>
#include<map>
#include<stack>
#include<string>
#include<random>
#include<cassert>
#include<functional>
#include<iomanip>
#define inf 0x3f3f3f3f
#define linf 0x3f3f3f3f3f3f3f3fll
#define endl '\n'
#define ll long long
// #define int long long
#define SZ(x) (int)x.size()
#define rep(i,a,n) for(int i = (a);i <= (n);i++)
#define dec(i,n,a) for(int i = (n);i >= (a);i--)
using namespace std;
using PII = pair<int, int>;
mt19937 mrand(random_device{}());
int rnd(int x) { return mrand() % x;}
const int N =10 + 2e5 ,mod=1e9 + 7;
/* 
    联通无向图, 起点1,朋友都在1,第i个朋友要去h_i
    k <= 6 no car 。有车的朋友可以让他们搭便车,但只能沿着最短路走
    输出最小走路的朋友
    最多n方的可能状态,对每一个有车f考虑,使得或值最大
    f[i][mask] |= f[i - 1][j] if(can find t | j == mask)
    
 */
void solve()
{    
    int n, m; cin >> n >> m;
    vector<vector<int>> adj(n + 1);
    rep(i, 1, m) {
        int u, v; cin >> u >> v;
        adj[u].emplace_back(v);
        adj[v].emplace_back(u);
    }    
    int fn; cin >> fn;
    vector<int> h(fn + 1);
    rep(i, 1, fn) cin >> h[i];
    int k; cin >> k;
    vector<int> p(k + 1);
    rep(i, 1, k) cin >> p[i];
    
    vector<int> state[n + 1];
    vector<vector<bool>> ex(n + 1, vector<bool>(1 << k));
    {
        queue<PII> q; q.push({1, 0});
        vector<bool> st(n + 1); 
        vector<int> dis(n + 1, -1); dis[1] = 0;
        state[1].push_back(0);
        ex[1][0] = 1;

        auto chk = [&](int x) {
            int ans = 0;
            rep(i, 1, k) if(x == h[p[i]]) ans |= (1 << (i - 1));
            return ans;
        };
        while(!q.empty()) {
            auto [u, fa] = q.front(); q.pop();
            if(~fa and dis[fa] + 1 == dis[u]) {
                int where = chk(u);
                for(auto x : state[fa]) if(!ex[u][where | x])
                    state[u].push_back(where | x), ex[u][where | x] = 1;
            }
            if(st[u]) continue;
            st[u] = 1;
            for(int v : adj[u]) if(v != fa) {
                if(dis[v] == -1) dis[v] = dis[u] + 1;
                q.push({v, u});
            }
        }
    }
    int ans = 0;
    {
        // f[i][mask] |= f[i - 1][j] if(can find t | j == mask)
        vector<vector<int>> f(fn - k + 1, vector<int>(1 << k, 0));
        f[0][0] = 1;
        int cur = 1;
        rep(i, 1, fn) {
            bool jump = 0;
            rep(j, 1, k) if(p[j] == i) jump = 1;
            if(jump) continue;

            rep(mask, 0, (1 << k) - 1) {
                for(auto t : state[h[i]]) {
                    rep(j, 0, (1 << k) - 1) if(mask == (t | j)) {
                        f[cur][mask] |= f[cur - 1][j];
                    }
                }
            }
            cur ++;
        }
        rep(mask, 0, (1 << k) - 1) if(f[fn - k][mask]) 
            ans = max(ans, __builtin_popcount(mask));
    }
    cout << k - ans << endl;

}
signed main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

    int T;cin>>T;
    while(T--)
        solve();

    return 0;
}

标签:int,压缩,cin,CF1741G,vector,include,rep,DP,define
From: https://www.cnblogs.com/Mxrush/p/16797001.html

相关文章

  • CF1746D(记忆化搜索,DP,贪心)
    CF1746D(记忆化搜索,DP,贪心)https://codeforces.com/contest/1746/problem/d题意给一棵树,树上每个点有一个权值\(s_i\),有一个整数\(k\)。表示从根节点出发的简单路径的......
  • Leetcode 6207 -- dp/思维/双指针
    题目描述maxmin思路思维代码classSolution{funccountSubarrays(_nums:[Int],_minK:Int,_maxK:Int)->Int{letsegments=nums.split......
  • AcWing 4706 -- 树形DP/DFS
    题目描述4706.最短路程思路dfs代码#include<iostream>#include<cstring>#include<algorithm>#include<vector>usingnamespacestd;constintN=100......
  • 2020CCPC秦皇岛-K. Kingdom's Power(树形DP + 贪心)
    题意给出一个有n个节点的有根树,1为根节点,根节点有无穷多个兵,每一秒可以让任意一个兵向任意一个地方移动一步,兵所到的点被占领,问最少需要经过多少秒,才能将所有的点都占领......
  • 82-java上传图片 并压缩
    privateBufferedImagegetNewImage(MultipartFileoldImage,doublewidth,doubleheight)throwsIOException{ /*srcURl原图地址;deskURL缩略图地址;comBase压缩基......
  • Sub-process /usr/bin/dpkg returned an error code (1)问题
     在用apt-get安装软件包的时候遇到E:Sub-process/usr/bin/dpkgreturnedanerrorcode(1)问题,解决方法如下:cd/var/lib/dpkg/sudomvinfo/info_bak......
  • 驱动开发:内核枚举DpcTimer定时器
    在笔者上一篇文章《驱动开发:内核枚举IoTimer定时器》中我们通过IoInitializeTimer这个API函数为跳板,向下扫描特征码获取到了IopTimerQueueHead也就是IO定时器的队列头,本章......
  • 【区间DP】ABC273F. Hammer 2
    ABC273F.Hammer2Difficulty:2277、关路灯模型区间DP题意略。思路设计dp状态:\(f[l][r][0/1]\)表示走完区间[l,r]最后待在l(0)或r(1)处的最小移动距离总和......
  • DP 优化
    决策单调性四边形不等式对于一个序列\(w\),称其满足四边形不等式当且仅当:\[\foralla<b\lec<d,w_{a,d}+w_{b,c}\gew_{a,c}+w_{b,d}\]\(\foralli,j,w_{i,j+1}+w_{i......
  • 用户数据报协议UDP
    UDP的首部格式如下:(1)源端口,源端口号。在需要对方回信时选用。不需要时可用全0。⑵目的端口,目的端口号。这在终点交付报文时必须使用。⑶长度,UDP用户数据报的长度,其最......