1 /*
  2    题意:有 n 个站点(编号1...n),每一个站点都有一个能量值,为了不让这些能量值连接起来,要用
  3    坦克占领这个站点!已知站点的 之间的距离,每个坦克从0点出发到某一个站点,1 unit distance costs 1 unit oil!
  4    最后占领的所有的站点的能量值之和为总能量值的一半还要多,问最少耗油多少!
  5
  6 */
  7
  8 /*
  9      思路:不同的坦克会占领不同的站点,耗油最少那就是路程最少,所以我们先将从 0点到其他各点的
 10      最短距离求出来!也就是d[i]的值!然后我们又知道每一个站点的所具有的能量值!也就是w[i];
 11      最后求出满足占领站点的能量比总能量的一半多并且路程最少。。。直接01背包走起!
 12 */
 13 #include<iostream>
 14 #include<queue>
 15 #include<cstring>
 16 #include<cstdio>
 17 #include<algorithm>
 18 #include<vector>
 19 #define N 10005
 20 #define INF 0x3f3f3f3f
 21 using namespace std;
 22
 23 int w[105];
 24
 25 struct EDGE{
 26    int u, v, nt, dist;
 27    EDGE(){}
 28
 29    EDGE(int u, int v, int nt, int dist){
 30       this->u=u;
 31       this->v=v;
 32       this->nt=nt;
 33       this->dist=dist;
 34    }
 35 };
 36
 37 EDGE edge[N*2];
 38 int first[105];
 39 int cnt;
 40 queue<pair<int, int> >q;
 41 int n, m;
 42 int dp[10005];
 43 int d[105];
 44 int map[105][105];
 45
 46 void addEdge(int u, int v, int dist){
 47     edge[cnt++]=EDGE(u, v, first[u], dist);
 48     first[u]=cnt-1;
 49     edge[cnt++]=EDGE(v, u, first[v], dist);
 50     first[v]=cnt-1;
 51 }
 52
 53 void Dijkstra(){
 54    d[0]=0;
 55    q.push(make_pair(0, 0));
 56    while(!q.empty()){
 57        pair<int,int> cur=q.front();
 58        q.pop();
 59        int u=cur.second;
 60        if(d[u] != cur.first) continue;
 61        for(int e=first[u]; e!=-1; e=edge[e].nt){
 62               int v=edge[e].v, dist=edge[e].dist;
 63               if(d[v] > d[u] + dist){
 64                  d[v] = d[u] + dist;
 65                  q.push(make_pair(d[v], v));
 66               }
 67        }
 68    }
 69 }
 70
 71 int main(){
 72    int t;
 73    int sumP, sumD;
 74    scanf("%d", &t);
 75    while(t--){
 76       scanf("%d%d", &n, &m);
 77       cnt=0;
 78       memset(d, 0x3f, sizeof(d));
 79       memset(first, -1, sizeof(first));
 80       for(int i=0; i<=n; ++i)
 81          for(int j=0; j<=n; ++j)
 82             map[i][j]=INF;
 83       while(m--){
 84           int u, v, dist;
 85           scanf("%d%d%d", &u, &v, &dist);
 86           if(map[u][v]>dist)
 87               map[u][v]=map[v][u]=dist;
 88       }
 89       for(int i=0; i<=n; ++i)
 90          for(int j=0; j<=i; ++j)
 91             if(map[i][j]!=INF)
 92               addEdge(i, j, map[i][j]);
 93       Dijkstra();//求出 0点到其他个点的最短的距离!
 94       sumP=sumD=0;
 95       for(int i=1; i<=n; ++i){
 96          scanf("%d", &w[i]);
 97          sumP+=w[i];
 98          sumD+=d[i];
 99       }
100       memset(dp, 0x3f, sizeof(dp));//初始背包的总价值为无穷大
101       dp[0]=0;
102
103       //zeroOnePackage... d[i]相当于价值(也就是耗油量), w[i]相当于容积(也就是能量值)
104       for(int i=1; i<=n; ++i)
105          for(int j=sumP; j>=w[i]; --j)
106             dp[j]=min(dp[j], dp[j-w[i]]+d[i]);
107
108       int maxCost=INF;
109       for(int i=sumP/2+1; i<=sumP; ++i)//注意是sumP/2+1(因为要比一半多)
110             if(maxCost>dp[i])
111                maxCost=dp[i];
112       if(maxCost==INF)
113          printf("impossible\n");
114       else printf("%d\n", maxCost);
115    }
116    return 0;
117 }
118 119 /*
120    思路:dp[i][j]表示到达 i站点, 并且占领的能量值为 j时的耗油最小值!
121          开始想用的是spfa算法,并且在进行节点之间距离松弛的时候,也将       背包融进来,但是超时啊!
122          好桑心.....
123 */
124
125 #include<iostream>
126 #include<queue>
127 #include<cstring>
128 #include<cstdio>
129 #include<algorithm>
130 #include<vector>
131 #define N 10005
132 #define INF 0x3f3f3f3f
133 using namespace std;
134
135 int w[105];
136
137 struct EDGE{
138    int u, v, nt, dist;
139    EDGE(){}
140
141    EDGE(int u, int v, int nt, int dist){
142       this->u=u;
143       this->v=v;
144       this->nt=nt;
145       this->dist=dist;
146    }
147 };
148
149 EDGE edge[N*2];
150 int first[105];
151 int cnt;
152 queue<pair<int, int> >q;
153 int vis[105];
154 int n, m, sum;
155 int dp[105][10005];
156 int map[105][105];
157
158 void addEdge(int u, int v, int dist){
159     edge[cnt++]=EDGE(u, v, first[u], dist);
160     first[u]=cnt-1;
161     edge[cnt++]=EDGE(v, u, first[v], dist);
162     first[v]=cnt-1;
163 }
164
165 void spfa(){
166    dp[0][0]=0;
167    q.push(make_pair(0, 0));
168    vis[0]=1;
169    while(!q.empty()){
170        pair<int,int> cur=q.front();
171        q.pop();
172        int u=cur.second;
173        vis[u]=0;
174        for(int e=first[u]; e!=-1; e=edge[e].nt){
175            int v=edge[e].v, dist=edge[e].dist;
176            for(int j=w[v]; j<=sum; ++j)
177               if(dp[v][j] > dp[u][j-w[v]] + dist){
178                  dp[v][j] = dp[u][j-w[v]] + dist;
179                  if(!vis[v]){
180                     vis[v]=1;
181                     q.push(make_pair(dp[v][j], v));
182                  }
183               }
184        }
185    }
186 }
187
188 int main(){
189    int t;
190    scanf("%d", &t);
191    while(t--){
192       scanf("%d%d", &n, &m);
193       cnt=0;
194       memset(first, -1, sizeof(first));
195       for(int i=0; i<=n; ++i)
196          for(int j=0; j<=n; ++j)
197             map[i][j]=INF;
198       while(m--){
199           int u, v, dist;
200           scanf("%d%d%d", &u, &v, &dist);
201           if(map[u][v]>dist)
202               map[u][v]=map[v][u]=dist;
203       }
204       for(int i=0; i<=n; ++i)
205          for(int j=0; j<=n; ++j)
206             if(map[i][j]!=INF)
207               addEdge(i, j, map[i][j]);
208       for(int i=1; i<=n; ++i){//最后将1...n节点的最优值汇聚到 第 n+1个节点上
209            edge[cnt++]=EDGE(i, n+1, first[i], 0);
210            first[i]=cnt-1;
211       }
212       sum=0;
213       for(int i=1; i<=n; ++i){
214          scanf("%d", &w[i]);
215          sum+=w[i];
216       }
217       w[n+1]=0;
218       for(int i=0; i<n+2; ++i)
219          for(int j=0; j<sum+2; ++j)
220             dp[i][j]=INF;
221       spfa();
222       int maxCost=INF;
223       for(int i=sum/2+1; i<=sum; ++i)
224             if(maxCost>dp[n+1][i])
225                maxCost=dp[n+1][i];
226       if(maxCost==INF)
227          printf("impossible\n");
228       else printf("%d\n", maxCost);
229    }
230    return 0;
231 } 

转载于:https://www.cnblogs.com/hujunzheng/p/3913288.html

hdu3339 In Action(Dijkstra+01背包)相关推荐

  1. nyoj 203 三国志 dijkstra+01背包

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=203 思路:先求点0到每个点的最短距离,dijkstra算法,然后就是01背包了 我奇怪的 ...

  2. HDU 3339 In Action 最短路+01背包

    题目链接: 题目 In Action Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...

  3. Java 01背包【动态规划·蓝桥杯练习题】(相信杨超越,相信锦鲤,默默努力,其它的看天意)

    锦鲤镇楼 1.题目描述: 时间限制:1.0s 内存限制:256.0MB 关键字:01背包 动态规划 问题描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间.更让他高 ...

  4. 【恋上数据结构】贪心(最优装载、零钱兑换、0-1背包)、分治(最大连续子序列和、大数乘法)

    贪心.分治 贪心(Greedy) 问题1:最优装载(加勒比海盗) 问题2:零钱兑换 零钱兑换的另一个例子 贪心注意点 问题3:0-1背包 0-1 背包 - 实例 一些习题 分治(Divide And ...

  5. hdu 2546 饭卡【贪心+01背包基础题】

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=2546 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  6. 计蒜客 7.22 K. Mario Kart(01背包+最短路)

    题意:在一个一维的坐标轴上,给定n个点的位置,还给定m种硬币,每个硬币都有一个C和V,C代表这种硬币的花费,V代表这种硬币可以传送的距离.题目还给定一个L,如果两个点之间的最小花费超过L那么两个点之间 ...

  7. 动态规划 背包问题小结 0-1背包(采药 九度第101题) 完全背包(Piggy-Bank POJ 1384) 多重背包(珍惜现在,感恩生活 九度第103题)

    本小结介绍0-1背包.完全背包以及多重背包问题 记忆要点: 0-1背包:二维数组情况下,顺序遍历体积或者倒序均可以                降维情况下需倒序遍历体积 完全背包:数组降维+顺序遍历 ...

  8. 浅说——九讲背包之01背包

    所谓九讲,也就是: 0/1背包 0/1背包降维 完全背包 多重背包(二进制优化) 混合背包 二维费用背包 分组背包 有依赖的背包 背包的方案总数\背包的具体方案路径 0/1背包: [问题描述](经典) ...

  9. Codeforces Round #104 (Div. 2) E DP(01背包模型) +组和+除法取模求逆元

    题意: 规定只包含4或7的数为幸运数字,给定n个数的序列,求他的子序列,使得该子序列的长度为k并且满足该子序列中不存在相同的两个幸运数字.问一共寻在多少种可能.(只要该数的下标不同则认为是不同的序列) ...

最新文章

  1. LaTeX - 带圈数字
  2. 菜鸟学python 哪吒_Python 学习之路 (前言)
  3. Android 任意区域截屏
  4. iptables复习记忆
  5. html div p 区别,html中div br p三者有什么区别?
  6. 硬件基础:电脑当中各个硬件的作用介绍
  7. Tomcat上具有JAX-WS的Web服务
  8. 5可视化数据大屏模板_可视化大屏模板分享
  9. Ubuntu网络配置相关相关
  10. 谷歌中巨大的 SEO 骗局!排名靠前的 HTML 编辑器也不可信
  11. java8之StringJoiner。终于有像guava类库里的功能了
  12. 凸优化学习笔记(五):凸优化算法、无约束优化算法、有约束优化算法
  13. IPMI IPMB协议
  14. python是由哪个人创造的文字_秦朝的文字是什么样的?是由谁创造出来的?
  15. jpg图片损坏怎么修复?可以试试这个方法
  16. 【NAS】群晖使用自带DDNS实现外网访问
  17. java学习(一)概述
  18. linux压缩文件恢复,Linux文件误删恢复
  19. Low Poly Epic City的脚本研究日志(2)(2022.3.1)
  20. Python实现艺术风格绘图

热门文章

  1. 完整性校验用到常见的算法_几种常见的校验算法
  2. shell脚本报错“^M: bad interpreter”解决方法
  3. SLF4J:Failed to load class org.slf4j.impl.StaticLoggerBinder
  4. JavaScript高级语法打包 - babel插件安装配置报错!Error: Cannot find module ‘@babel/preset-preset.env‘
  5. uniapp页面传参使用encodeURIComponent转义特殊符号
  6. 云计算体系结构中soa构建层_云计算的服务模式及技术结构
  7. python以写模式打开录入_Python的学习(六)—-文件和输入输出处理 | 学步园
  8. 怎么时装linux可用空间变大,[合集]OpenSUSE安装octave时装1G多texliv - 精华区 - 优秀的Free OS(Linux)版 - 北大未名BBS...
  9. centos mysql rpm re_centos7和centos6.5环境rpm方式安装mysql5.7和mysql5.6详解
  10. c语言学生成绩查询系统2018,南昊网上阅卷学生成绩查询系统