SCU 1095运送物资(最短路)

X国发生了内战。起义军得到了广大人民的支持。在一次战役中,反动军队结集了大量兵力,围攻起义军的主堡W城。为支援前线,后方各个供给基地城市纷纷准备将物资运往W城。各基地及W城之间有的有公路相连。这就是说,有的基地不能将物资一次运到W城,必须通过中途的转运。

根据每条公路的长短和运送物资的多少,运送中将会有不同程度的损耗。现假设每条公路都有一个损耗系数,表示经过这条公路的物资总量与消耗量的比值。

另外,为保证物资安全到达,每个基地都会等所有要通过该基地转运的物资到齐后,连同本基地的物资一起,运到下一站。也就是说,从任何一个基地出发,都只能将物资运往另一基地,但允许多个基地的物资运往同一基地。

请编程预定出每个基地的运输路线,使到达W城的总物资最大。

输入:{input.txt}

第一行给出两个整数n(2<=n<=100)与m。其中n表示有n-1个基地(编号为1到n)与一个W城(编号为n);m表示有m条公路。

第二行给出了n-1个正整数(正整数<=50000),表示编号为1到n-1的基地要运送的物资数量。

接下来m行描述了m条公路的情况,每一行有3个数,如 1 2 0.1

表示1号城市与2号城市之间有一条公路连接,其损耗系数为0.1。

注意:数据给出的公路网,保证每个基地都能将物资运到W城。

输出:{ouput.txt}

共n行。

第一行是运到W城的最大物资数(结果保留两位小数)。

接下来n-1行分别有一个数,代表每个基地将物资运往的下一个基地或W城的编号。

样例输入

5 6

10 10 10 10

1 3 0

1 4 0

2 3 0

2 4 0

3 5 0

4 5 0

样例输出

40.00

3

3

5

5

解题报告

裸的最短路,在将边的权值表示为(1-损耗)的倒数。因为精度问题,倒数要开long double,并除以100,在计算路径时不是加而是乘。

#include<bits/stdc++.h>
#include<queue>
#include <algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#define Pair pair<long double,int>
#define MAXN 1000+10
#define MAXM 600000+1
using namespace std;
int n,m,num,head[MAXN],s,t,pre[MAXN],v[MAXM];
double good[MAXN],ans;
long double dis[MAXN];
struct Edge{
int next,to,exi,from;
double dis;
}edge[MAXM];
void add(int from,int to,double dis)
{
edge[++num].next=head[from];
edge[num].to=to;
edge[num].dis=dis;
edge[num].from=from;
head[from]=num;
}
void dij()
{
memset(dis,,sizeof(dis));
memset(pre,,sizeof(pre));
memset(v,,sizeof(v));
priority_queue<Pair,vector<Pair>,greater<Pair> > h;
for(int i=;i<=n;i++) dis[i]=LONG_LONG_MAX;
dis[s]=*0.001;
h.push(Pair(dis[s],s));
while(h.size()>)
{
int k=h.top().second;h.pop();
if(v[k]) continue;
v[k]=;
for(int i=head[k];i;i=edge[i].next)
{
if(((dis[k]*edge[i].dis))<(dis[edge[i].to]))
{
dis[edge[i].to]=dis[k]*edge[i].dis;
pre[edge[i].to]=edge[i].from;
h.push(Pair(dis[edge[i].to],edge[i].to));
}
} }
}
int main()
{ scanf("%d%d",&n,&m);
for(int i=;i<=n-;i++)
scanf("%lf",&good[i]);
for(int i=;i<=m;i++)
{
int x,y;double z;
scanf("%d%d%lf",&x,&y,&z);
add(x,y,/(-z));
add(y,x,/(-z));
}
s=n;
dij();
for(int i=;i<=n-;i++)
ans+=good[i]*(0.001/dis[i]);
printf("%.2lf\n",ans);
for(int i=;i<=n-;i++)
{
printf("%d\n",pre[i]);
} return ;
}

最新文章

  1. POJ 2464 Brownie Points II(树状数组)
  2. 3D touch 静态、动态设置及进入APP的跳转方式
  3. 高仿700Bike的界面图片
  4. c# 改变图片的大小(w,h)
  5. UI进阶 动画
  6. CF29D - Ant on the Tree(DFS)
  7. 深入浅出 - Android系统移植与平台开发(十)- Android编译系统与定制Android平台系统(瘋耔修改篇二)
  8. SVN:重命名文件之后不允许提交
  9. 新一代开源Android渠道包生成工具Walle
  10. Dev中GridControl的GridView 基本样式设置
  11. c#中WebApi开发遇到的坑
  12. Linux Performance 一文
  13. 手机端适配方案 媒体查询和flexbale
  14. Quartz框架多个trigger任务执行出现漏执行的问题分析--转
  15. ubuntu upstart启动流程分析
  16. Java字符串分割
  17. js中call与apply的区别以及使用~
  18. (windows下)tomcat优化--内存,并发.缓存三方面优化
  19. 关联容器:unordered_map详细介绍(附可运行代码)
  20. MNIST数据集转化为二维图片

热门文章

  1. swift 20 - Nested Types
  2. 解决vuex刷新页面数据丢失
  3. Node_进阶_8
  4. NodeJS学习笔记 (5)网络服务-http-req(ok)
  5. Generator 简介
  6. Docker学习总结(10)——10分钟玩转Docker
  7. hdu2236
  8. Java - Thinking in Java 第2章 一切都是对象
  9. 6. MongoDB——Java操作(增删改查)
  10. 数据结构之fhq-treap