Dig The Wells

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 971    Accepted Submission(s): 416

Problem Description
You may all know the famous story “Three monks”. Recently they find some places around their temples can been used to dig some wells. It will help them save a lot of time. But to dig the well or build the road to transport the water
will cost money. They do not want to cost too much money. Now they want you to find a cheapest plan.
 
Input
There are several test cases.

Each test case will starts with three numbers n , m, and p in one line, n stands for the number of monks and m stands for the number of places that can been used, p stands for the number of roads between these places. The places the monks stay is signed from
1 to n then the other m places are signed as n + 1 to n + m. (1 <= n <= 5, 0 <= m <= 1000, 0 <=p <= 5000)

Then n + m numbers followed which stands for the value of digging a well in the ith place.

Then p lines followed. Each line will contains three numbers a, b, and c. means build a road between a and b will cost c.
 
Output
For each case, output the minimum result you can get in one line.
 
Sample Input
3 1 3
1 2 3 4
1 4 2
2 4 2
3 4 4
4 1 4
5 5 5 5 1
1 5 1
2 5 1
3 5 1
4 5 1
 
Sample Output
6
5

题意:有n个和尚。每个和尚一个庙,有m个村庄,p条路。每条路有费用,每个地方打井也须要费用,求最少花多少钱能够使得全部和尚喝上水。

斯坦纳树比較裸的问题。

代码:

/* ***********************************************
Author :rabbit
Created Time :2014/7/17 0:59:57
File Name :13.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 100000000
#define eps 1e-8
#define pi acosi
typedef long long ll;
int head[1100],tol;
struct Edge{
int next,to,val;
}edge[1001000];
void addedge(int u,int v,int w){
edge[tol].to=v;
edge[tol].next=head[u];
edge[tol].val=w;
head[u]=tol++;
}
int weight[1100],d[1100][1<<5],dp[1100],in[1010][1<<5];
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
int n,m,p;
while(~scanf("%d%d%d",&n,&m,&p)){
memset(head,-1,sizeof(head));tol=0;
for(int i=0;i<n+m;i++)
scanf("%d",&weight[i]);
while(p--){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
u--;v--;
addedge(u,v,w);
addedge(v,u,w);
}
for(int i=0;i<n+m;i++)
for(int j=0;j<(1<<n);j++)
d[i][j]=INF;
for(int i=0;i<(1<<n);i++)dp[i]=INF;
memset(in,0,sizeof(in));
for(int i=0;i<n;i++)
d[i][1<<i]=weight[i];
for(int i=1;i<(1<<n);i++){
queue<int> Q;
for(int j=0;j<n+m;j++){
for(int k=i&(i-1);k;k=(k-1)&i)
d[j][i]=min(d[j][i],d[j][i-k]+d[j][k]-weight[j]);
if(d[j][i]<INF)Q.push(100000*j+i),in[j][i]=1;
}
while(!Q.empty()){
int v=Q.front()/100000,t=Q.front()%100000;
Q.pop();
in[v][t]=0;
for(int e=head[v];e!=-1;e=edge[e].next){
int s=edge[e].to;
if(d[s][t]>d[v][t]+edge[e].val+weight[s]-weight[v]){
d[s][t]=d[v][t]+edge[e].val+weight[s]-weight[v];
if(!in[s][t]){
in[s][t]=1;
Q.push(100000*s+t);
}
}
}
}
}
for(int i=1;i<(1<<n);i++)
for(int j=0;j<n+m;j++)
dp[i]=min(dp[i],d[j][i]);
for(int i=1;i<(1<<n);i++){
for(int j=i&(i-1);j;j=i&(j-1))
dp[i]=min(dp[i],dp[j]+dp[i-j]);
}
cout<<dp[(1<<n)-1]<<endl;
}
return 0;
}

HDU 4085 Steiner树模板称号的更多相关文章

  1. HDU 4085 Steiner树

    主题链接:pid=4085">http://acm.hdu.edu.cn/showproblem.php? pid=4085 由于这题专门花一晚上学习斯坦纳树.找到比較好的学习资料,链 ...

  2. HDU 1251 Trie树模板题

    1.HDU 1251 统计难题  Trie树模板题,或者map 2.总结:用C++过了,G++就爆内存.. 题意:查找给定前缀的单词数量. #include<iostream> #incl ...

  3. HDU 1166 线段树模板&树状数组模板

    HDU1166 上好的线段树模板&&树状数组模板 自己写的第一棵线段树&第一棵树状数组 莫名的兴奋 线段树: #include <cstdio> using nam ...

  4. HDU - 1251 字典树模板题

    Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).  Input输入数据的第一部 ...

  5. HDU(1166),线段树模板,单点更新,区间总和

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 第一次做线段树,帆哥的一句话,我记下来了,其实,线段树就是一种处理数据查询和更新的手段. 然后, ...

  6. hdu 2072(字典树模板,set,map均可做)

    地址:http://acm.hdu.edu.cn/showproblem.php?pid=2072 lily的好朋友xiaoou333最近很空,他想了一件没有什么意义的事情,就是统计一篇文章里不同单词 ...

  7. hdu 1754 线段树模板题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 #include <cstdio> #include <cmath> # ...

  8. hdu 1251 字典树模板题 ---多串 查找单词出现次数

    这道题题目里没有给定数据范围 我开了2005  疯狂的WA 然后开了50000, A掉  我以为自己模板理解错  然后一天没吃饭,饿得胃疼还是想着把这题A掉再去吃,谁知竟然是这样的问题,,,呵呵~~~ ...

  9. hdu 2665 划分树模板题(可作为模板)

    Kth number Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

随机推荐

  1. css3仿山猫侧边栏

    演示:http://jsfiddle.net/Adce2/ 其主要思想: 1, 先画边栏html. 2, 使用css3分别财产close sidebar-content动图片. 3, 使用css3的k ...

  2. 递归遍历XML所有节点

    package xml; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.DocumentEx ...

  3. Ubuntu下用NdisWrapper安装网卡驱动

    下面是一个简单全面的使用NdisWrapper的指南.这是从Beginning Ubuntu Linux, Second Edition中提炼出来的. 这份指南是第8章的一部分.该章给出了在Ubunt ...

  4. 《HBase权威指南》读书笔记----简介

    工作中要使用HBase,刚刚开始接触HBase,理解不深,只是记录一下 . HBase基于google的bigtable论文实现,属于nosql. 几个概念: (1)列(column):最基本单位为列 ...

  5. Preference如何增加在activity生命周期监听器

    转载请注明出处:http://blog.csdn.net/droyon/article/details/41313115 本文主要介绍Preference凭什么Activit一些逻辑的生命周期,使. ...

  6. C# 视频教程

    http://www.cnblogs.com/kellen/tag/Silverlight/ http://www.lanmaodream.com/archives/244.html

  7. 《实验数据的结构化程序设计》 2.4.4Calendar个人意见,寻求指引

    题目大意: 制作一个日历系统,输入年份.一些周年纪念日,及服务要求日期,依据要求日期输出,输出重要程度小于发生日期的周年纪念日. 题目地址: UVA  145 个人见解: 纯模拟,在闰年,输出顺序及输 ...

  8. Oracle 11g client安装和配置。

    数据库和client在不同的机器. 安装前的准备.在安装过程中Oracle数据库server导航到下面的文件夹. 将listener.ora和tnsnames.ora中的host中的localhost ...

  9. 使用 Cordova+Visual Studio 创建跨平台移动应用(3)

    1 背景 本章节是关于Telerik AppBuilder for Visual Studio的. 目前(2014.12)为Telerik公司Telerik Platform的一部分,Telerik ...

  10. SSh框架结构(Struts2.1+Hibernate4.0+Spring3.1)

    一个.使用的工具 开发工具:My Eclipse 10.7以及对应的java开发工具 框架版本号:Struts2.1+Hibernate3+Spring3.0 数据库:MySql5.5 Mysql可视 ...