HDU 4640 Island and study-sister(状态压缩)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4640

题意:给出一个无向图,边有权值。三个人初始时呆在1号点。在其余n-1个点中有些点要求被遍历到。且除了1号点之外每个点最多只能被一个人遍历。求要求被遍历的点中最后被遍历的点的最小时刻。

思路:用f[st][i]表示一个人遍历完集合st最后停在i的最小时间,之后用f[st][i]得到f1[st],表示遍历完集合st的最小时间。然后得到dp[i][st]表示i个人遍历完st的最小时间。

int g[N][N],n,m,K,st;
int f[1<<N][N],dp[4][1<<N];
int f1[1<<N];

struct node
{
    int st,x;

    node(){}
    node(int _st,int _x)
    {
        st=_st;
        x=_x;
    }
};

int visit[1<<N][N];

void init()
{
    int i,j,k;
    FOR0(i,(1<<n)) FOR0(j,n) f[i][j]=INF,visit[i][j]=0;
    f[1][0]=0;
    queue<node> Q;
    Q.push(node(1,0));

    while(!Q.empty())
    {
        node u=Q.front();
        Q.pop();

        visit[u.st][u.x]=0;
        FOR0(i,n) if(f[u.st|(1<<i)][i]>f[u.st][u.x]+g[u.x][i])
        {
            f[u.st|(1<<i)][i]=f[u.st][u.x]+g[u.x][i];
            if(!visit[u.st|(1<<i)][i])
            {
                visit[u.st|(1<<i)][i]=1;
                Q.push(node(u.st|(1<<i),i));
            }
        }
    }
    FOR0(i,(1<<n)) f1[i]=INF;
    FOR0(i,(1<<n)) FOR0(j,n) upMin(f1[i],f[i][j]);

    FOR0(i,4) FOR0(j,(1<<n)) dp[i][j]=INF;
    FOR0(i,(1<<n)) dp[1][i]=f1[i];
    for(i=2;i<=3;i++) for(j=0;j<(1<<n);j++)
    {
        k=j;
        while(k)
        {
            upMin(dp[i][j],max(dp[1][k|1],dp[i-1][(j^k)|1]));
            k=(k-1)&j;
        }
    }
}

int main()
{
    int num=0;
    rush()
    {
        RD(n,m);
        int i,j,k,w;
        FOR0(i,n) FOR0(j,n) g[i][j]=INF;
        FOR0(i,n) g[i][i]=0;
        FOR0(i,m)
        {
            RD(j,k,w);j--;k--;
            if(g[j][k]>w) g[j][k]=g[k][j]=w;
        }
        st=1;
        RD(K);
        FOR0(i,K) RD(j),j--,st|=1<<j;
        printf("Case %d: ",++num);
        init();
        int ans=INF;
        FOR1(i,3) FOR0(j,(1<<n)) if((j&(st))==st)
        {
            upMin(ans,dp[i][j]);
        }
        if(ans==INF) ans=-1;
        PR(ans);
    }
}

HDU 4640 Island and study-sister(状态压缩),布布扣,bubuko.com

时间: 2024-09-30 02:00:07

HDU 4640 Island and study-sister(状态压缩)的相关文章

HDU 4640 Island and study-sister(状态压缩DP+路径压缩)经典 旅行商问题

Island and study-sister Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 790    Accepted Submission(s): 273 Problem Description Members of ACM/ICPC teams of Fuzhou University always stay in th

HDU 3001 Travelling (三进制状态压缩 DP)

题意:有 n 个city,可以选择任一城市作为起点,每个城市不能访问超过2次, 城市之间有权值,问访问全部n个城市需要的最小权值. 思路:因为每个城市可以访问最多两次,所以用三进制表示访问的状态. 详细见代码注释!!!! #include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map> #include<cmath> #inclu

[ACM] HDU 1400 Mondriaan&#39;s Dream (状态压缩,长2宽1长方形铺满)

Mondriaan's Dream Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 783    Accepted Submission(s): 506 Problem Description Squares and rectangles fascinated the famous Dutch painter Piet Mondri

HDU 5418 Victor and World (状态压缩dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5418 题目大意:有n个结点m条边(有边权)组成的一张连通图(n <16, m<100000).求从第一个点出发,经过每个点至少一次后回到原点的最小路径边权和. 分析:发现我还真是菜. n<16,很明显的状态压缩标记,先将所有点的编号减去1,使其从0开始编号.dp[i][j]表示从0号点出发,当前状态为i (二进制位为1表示对应点已走过,否则没走过), 当前位置为 j,  回到原点的最小代价,

HDU 6607 Time To Get Up(状态压缩+枚举)

题目网址: http://acm.hdu.edu.cn/showproblem.php?pid=6077 思路: 先预处理一下,将每个数字块的"X"看作1,"."看作0,进行状态压缩转换成二进制数,用数组保存.再遍历每个块点的元素,枚举0-9看是否符合当前位数. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 typedef long long l

HDU 5418——Victor and World——————【状态压缩+floyd】

Victor and World Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java/Others)Total Submission(s): 891    Accepted Submission(s): 399 Problem Description After trying hard for many years, Victor has finally received a pilot li

[ACM] HDU 5025 Saving Tang Monk (状态压缩,BFS)

Saving Tang Monk Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 941    Accepted Submission(s): 352 Problem Description <Journey to the West>(also <Monkey>) is one of the Four Great Clas

HDU 4336 Card Collector (期望DP+状态压缩 或者 状态压缩+容斥)

题意:有N(1<=N<=20)张卡片,每包中含有这些卡片的概率,每包至多一张卡片,可能没有卡片.求需要买多少包才能拿到所以的N张卡片,求次数的期望. 析:期望DP,是很容易看出来的,然后由于得到每张卡片的状态不知道,所以用状态压缩,dp[i] 表示这个状态时,要全部收齐卡片的期望. 由于有可能是什么也没有,所以我们要特殊判断一下.然后就和剩下的就简单了. 另一个方法就是状态压缩+容斥,同样每个状态表示收集的状态,由于每张卡都是独立,所以,每个卡片的期望就是1.0/p,然后要做的就是要去重,既然

hdu 5023 线段树延迟更新+状态压缩

/* 线段树延迟更新+状态压缩 */ #include<stdio.h> #define N 1100000 struct node { int x,y,yanchi,sum; }a[N*4]; int lower[31]; void build(int t,int x,int y) { a[t].x=x; a[t].y=y; a[t].yanchi=0; if(x==y){ a[t].sum=lower[1]; return ; } int temp=t<<1; int mid=