hdu3311Dig The Wells

原创 2016年08月29日 13:34:51

链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3311

题意:n个和尚住的地方,m个其他地方。每个地方挖一口井需要花费q[i]的钱,两个地方连通需要花费对应的边权值。求所有人都能喝到水的最小花费。

分析:斯塔纳树。如hdu4085,只要在加一位二进制表示集合内是否已经有水了即可。详见代码。

代码:

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<bitset>
#include<math.h>
#include<vector>
#include<string>
#include<stdio.h>
#include<cstring>
#include<iostream>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int N=1010;
const int mod=1000000007;
const int MOD1=1000000007;
const int MOD2=1000000009;
const double EPS=0.00000001;
typedef long long ll;
const ll MOD=1000000007;
const int INF=1000000010;
const ll MAX=1ll<<55;
const double eps=1e-5;
const double inf=~0u>>1;
const double pi=acos(-1.0);
typedef double db;
typedef long double ldb;
typedef unsigned int uint;
typedef unsigned long long ull;
queue<int>Q;
int n,m,p,K,T,e[N],q[N];
int dp[N][80],bo[100*N],ans[80];
int tot,u[N],v[10*N],w[10*N],pre[10*N];
inline void add(int a,int b,int c) {
    v[tot]=b;w[tot]=c;pre[tot]=u[a];u[a]=tot++;
    v[tot]=a;w[tot]=c;pre[tot]=u[b];u[b]=tot++;
}
inline void init() {
    int i,j,a,b,c;
    K=n+m;T=1<<n;
    memset(bo,0,sizeof(bo));
    tot=0;memset(u,-1,sizeof(u));
    memset(e,0,sizeof(e));
    for (i=0;i<n;i++) e[i+1]=1<<i;
    for (i=1;i<=K;i++) scanf("%d", &q[i]);
    for (i=1;i<=K;i++)
        for (j=0;j<T*2;j++) dp[i][j]=INF;
    for (i=1;i<=K;i++) dp[i][0]=dp[i][0|e[i]]=0,dp[i][T]=dp[i][T|e[i]]=q[i];
    for (i=1;i<=p;i++) {
        scanf("%d%d%d", &a, &b, &c);add(a,b,c);
    }
}
inline void spfa() {
    int i,x,y,z;
    while (!Q.empty()) {
        x=Q.front();Q.pop();bo[x]=0;
        y=x%100;x/=100;z=y/T;y%=T;
        for (i=u[x];i!=-1;i=pre[i]) {
            if (!z&&dp[v[i]][y]>dp[x][y]+w[i]) {
                dp[v[i]][y]=dp[x][y]+w[i];
                if (!bo[v[i]*100+y]) bo[v[i]*100+y]=1,Q.push(v[i]*100+y);
            }
            if (!z&&dp[v[i]][y|T]>dp[x][y]+w[i]+q[v[i]]) {
                dp[v[i]][y|T]=dp[x][y]+w[i]+q[v[i]];
                if (!bo[v[i]*100+(y|T)]) bo[v[i]*100+(y|T)]=1,Q.push(v[i]*100+(y|T));
            }
            if (z&&dp[v[i]][y|T]>dp[x][y|T]+w[i]) {
                dp[v[i]][y|T]=dp[x][y|T]+w[i];
                if (!bo[v[i]*100+(y|T)]) bo[v[i]*100+(y|T)]=1,Q.push(v[i]*100+(y|T));
            }
        }
    }
}
inline void Steiner_Tree() {
    int i,j,k;
    for (i=0;i<T;i++) {
        for (j=1;j<=K;j++)
            for (k=i;k;k=(k-1)&i) {
                dp[j][i]=min(dp[j][i],dp[j][k]+dp[j][i-k]);
                dp[j][i|T]=min(dp[j][i|T],dp[j][k|T]+dp[j][i-k]);
                dp[j][i|T]=min(dp[j][i|T],dp[j][k]+dp[j][(i-k)|T]);
            }
        for (j=1;j<=K;j++) {
            if (dp[j][i]!=INF) bo[j*100+i]=1,Q.push(j*100+i);
            if (dp[j][i|T]!=INF) bo[j*100+(i|T)]=1,Q.push(j*100+(i|T));
        }
        spfa();
    }
}
void getans() {
    for (int i=0;i<T;i++) ans[i]=INF;
    for (int i=0;i<T;i++)
        for (int j=1;j<=K;j++) ans[i]=min(ans[i],dp[j][i|T]);
    for (int i=0;i<T;i++)
        for (int j=i;j;j=(j-1)&i) ans[i]=min(ans[i],ans[j]+ans[i-j]);
    printf("%d\n", ans[T-1]);
}
int main()
{
    while (scanf("%d%d%d", &n, &m, &p)!=EOF) {
        init();
        Steiner_Tree();
        getans();
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

Hdu 3311 Dig The Wells (综合_斯坦纳树)

Zoj 3613 Wormhole Transport (综合_斯坦纳树) 分类: 全部博客 ACM_动态规划(DP) ACM_数据结构 ACM_图论系列2012-09-05 00:16...
  • pi9nc
  • pi9nc
  • 2013年08月14日 21:30
  • 690

HDU3311Dig The Wells(斯坦纳树,spfa+状态压缩DP)可作模板

Dig The Wells Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...
  • u010372095
  • u010372095
  • 2015年03月26日 22:23
  • 1053

wells 效果 (Bootstrap)

首先看看wells效果如下:FR:徐海涛(Hunk Xu)
  • qq_15267341
  • qq_15267341
  • 2017年01月05日 16:43
  • 249

hdu 3311 Dig The Wells (SteinerTree斯坦纳树)

Problem Description You may all know the famousstory “Three monks”. Recently they find some places a...
  • lphy2352286B
  • lphy2352286B
  • 2014年03月05日 22:36
  • 1048

HDU-3311-Dig The Wells

ACM模版描述题解斯坦纳树,模版题,状压dp,还是无法很好地理解,找了大牛们的blog,感觉好高大上……以下来自Staginner大牛的博客……这个和一般的斯坦纳树的题目不同的地方在于挖井要加点权,但...
  • f_zyj
  • f_zyj
  • 2016年11月07日 01:34
  • 366

HDU3311-Dig The Wells

Dig The Wells                                                                    Time Limit: 6000/2...
  • a664607530
  • a664607530
  • 2017年11月13日 20:17
  • 119

HDOJ 3311 Dig The Wells

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3311 题目大意: 现在有n个寺庙和m个城市, 在这个n + m个城市之间有p条道路。 在道路上...
  • frog1902
  • frog1902
  • 2014年01月21日 19:25
  • 822

Bootstrap学习笔记 08 - Wells

WellsnormalNormal WellsmallSmall WelllargeLarge Well
  • u011304970
  • u011304970
  • 2017年11月02日 09:00
  • 115

Bootstrap学习:Wells

Well 是一种会引起内容凹陷显示或插图效果的容器 。为了创建 Well,只需要简单地把内容放在带有 class .well 的 中即可。下面的实例演示了一个默认的 Well: html> h...
  • scholar_man
  • scholar_man
  • 2015年09月02日 14:13
  • 452

Wells, Hitler and the World State

In March or April, say the wiseacres, there is to be a stupendous knockout blow at Britain... What H...
  • lililingling1985
  • lililingling1985
  • 2006年09月11日 02:24
  • 410
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hdu3311Dig The Wells
举报原因:
原因补充:

(最多只允许输入30个字)