zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 190 E

    题意

    (N) 个数,其中 (M) 对数可以相邻,求出包含所给序列 (C) 的最短序列的长度。(1leq Nleq 10^5,1leq Mleq10^5,1leq K leq17)
    题目链接:https://atcoder.jp/contests/abc190/tasks/abc190_e

    分析

    可以发现 (K) 很小,应该如何利用?令 (dp[i][j]) 表示包含 (i) 方案,且最近一个位置是第 (j) 个位置的最少花费,其中 (i) 为状态,为 (1) 的二进制位表示该位置的数字已经包含。那么 (dp[nextstate][j]=min(dp[nextstate][j],dp[i][j]+dis[j][x])),其中 (nextstate=i+(1<<x))(dis[j][x]) 可通过 (bfs) 求出。

    代码

    #include <bits/stdc++.h>
    #define pb push_back
    using namespace std;
    const int inf=0x3f3f3f3f;
    const int N=1e5+5;
    const int maxn=2e5+5;
    int dis[20][N],n,dp[maxn][20],k,c[20];
    vector<int>pic[N];
    bool vis[N];
    void bfs(int s)
    {
        queue<int>que;
        for(int i=1;i<=n;i++) vis[i]=0;
        que.push(c[s]);
        dis[s][c[s]]=0;
        vis[c[s]]=1;
        while(!que.empty())
        {
            int now=que.front();
            que.pop();
            for(auto v:pic[now])
            {
                if(vis[v]) continue;
                dis[s][v]=dis[s][now]+1;
                vis[v]=1;
                que.push(v);
            }
        }
    }
    int main()
    {
        int m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            pic[a].pb(b);
            pic[b].pb(a);
        }
        scanf("%d",&k);
        for(int i=0;i<k;i++)
            scanf("%d",&c[i]);
        for(int i=0;i<k;i++)
            for(int j=1;j<=n;j++)
                dis[i][j]=inf;
        for(int i=0;i<k;i++)
            bfs(i);
        for(int i=0;i<(1<<k);i++)
            for(int j=0;j<k;j++)
                dp[i][j]=inf;
        for(int i=0;i<k;i++) dp[(1<<i)][i]=1;
        for(int i=0;i<(1<<k);i++)
        {
            for(int j=0;j<k;j++)
            {
                if(dp[i][j]==inf) continue;
                for(int x=0;x<k;x++)
                {
                    if(x==j||dis[j][c[x]]==inf) continue;
                    if((i>>x)&1) continue;
                    int nextstate=i+(1<<x);
                    dp[nextstate][x]=min(dp[i][j]+dis[j][c[x]],dp[nextstate][x]);
                }
            }
        }
        int ans=inf;
        for(int i=0;i<k;i++) ans=min(dp[(1<<k)-1][i],ans);
        if(ans>=inf) printf("-1
    ");
        else printf("%d
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    杭电1176解答免费馅饼
    Locust 关联
    Locust 参数化
    Locust 介绍篇
    Locust 集合点
    Locust 其他协议
    团队项目需求分析报告
    第一次个人编程作业
    团队项目选题报告
    第一次软工作业
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/14352096.html
Copyright © 2011-2022 走看看