L3-005. 垃圾箱分布

时间限制
200 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越

大家倒垃圾的时候,都希望垃圾箱距离自己比较近,但是谁都不愿意守着垃圾箱住。所以垃圾箱的位置必须选在到所有居民点的最短距离最长的地方,同时还要保证每个居民点都在距离它一个不太远的范围内。

现给定一个居民区的地图,以及若干垃圾箱的候选地点,请你推荐最合适的地点。如果解不唯一,则输出到所有居民点的平均距离最短的那个解。如果这样的解还是不唯一,则输出编号最小的地点。

输入格式:

输入第一行给出4个正整数:N(<= 103)是居民点的个数;M(<= 10)是垃圾箱候选地点的个数;K(<= 104)是居民点和垃圾箱候选地点之间的道路的条数;DS是居民点与垃圾箱之间不能超过的最大距离。所有的居民点从1到N编号,所有的垃圾箱候选地点从G1到GM编号。

随后K行,每行按下列格式描述一条道路:
P1 P2 Dist
其中P1和P2是道路两端点的编号,端点可以是居民点,也可以是垃圾箱候选点。Dist是道路的长度,是一个正整数。

输出格式:

首先在第一行输出最佳候选地点的编号。然后在第二行输出该地点到所有居民点的最小距离和平均距离。数字间以空格分隔,保留小数点后1位。如果解不存在,则输出“No Solution”。

输入样例1:

4 3 11 5
1 2 2
1 4 2
1 G1 4
1 G2 3
2 3 2
2 G2 1
3 4 2
3 G3 2
4 G1 3
G2 G1 1
G3 G2 2

输出样例1:

G1
2.0 3.3

输入样例2:

2 1 2 10
1 G1 9
2 G1 20

输出样例2:

No Solution
 

刚开始题目意思比较难理解:“选在到所有居民点的最短距离最长的地方”。首先知道题目中对答案的限制条件只有一个,那就是最大距离不能超过Ds,那么对在此基础上筛选下来的候选位置中计算他们各自的到所有居民区的最短距离,比如我G1到1号1米,2号2米,3号3米;G2到1号6米,到2号5米,到3号10米,那么G1的最短就是1米(一号),G2的最短距离就是5米(二号)。

以此类推对每一个筛选出来的候选位置都计算对应的min_dx。然后当然此前要对筛选出来的答案存放到数组,然后排序一下。这题比较杯具的是交了N多次,刚开始是用map写邻接表,超时,改为vector,终于不超时了,可是总是最后一个组WA,不解,接着改啊改……WA数次之后发现是自定义排序规则里一个变量写错了。真的是无语了。原本还以为这题的坑点是不一定1~N的所有点和垃圾桶位置,还搞了个set存放位置,现在看来题目还是比较友好的……

代码:

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define MM(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long LL;
const int N=10020;
typedef pair<int,double> psd;
vector<psd>E[1050];
double d[N];
int n,m,k;
double ds;
inline int bianhao(char s[])
{
int len=strlen(s);
int r=0;
if(s[0]=='G')
{
for (int i=1; i<len; i++)
r=r*10+(s[i]-'0');
return 1000+r;
}
else
{ for (int i=0; i<len; i++)
r=r*10+(s[i]-'0');
return r;
}
}
inline void spfa(const int &s,const int &t)
{
d[s]=0;
priority_queue<pair<double,int> >Q;
Q.push(pair<double,int>(-d[s],s));
while (!Q.empty())
{
int now=Q.top().second;
Q.pop();
for (int i=0; i<E[now].size(); i++)
{
int v=E[now][i].first;
if(d[v]>d[now]+E[now][i].second)
{
d[v]=d[now]+E[now][i].second;
Q.push(pair<double,int>(-d[v],v));
}
}
}
}
struct info
{
int s;
double aver,sum,minm;
info(const int &ss,const double &av,const double &su,const double &mm):s(ss),aver(av),sum(su),minm(mm){}
info(){}
};
bool cmp(const info &a,const info &b)
{
if(a.minm!=b.minm)
return a.minm>b.minm;//就是这个地方写成了a.minm>b.sum,强行WA数次- -
if(a.aver!=b.aver)
return a.aver<b.aver;
else
return a.s<b.s;
}
int main(void)
{
int i,j;
while (~scanf("%d%d%d%lf",&n,&m,&k,&ds))
{
for (i=0; i<1050; i++)
E[i].clear();
char s[5],t[5];
int S,T;
double dx;
for (i=0; i<k; i++)
{
scanf("%s%s%lf",s,t,&dx);
S=bianhao(s);
T=bianhao(t);
E[S].push_back(psd(T,dx));
E[T].push_back(psd(S,dx));
}
info ans[1000];int cnt=0;
for (i=1; i<=m; i++)
{
memset(d,0x43,sizeof(d));
for (j=1; j<=n; j++)
spfa(i+1000,j);
bool flag=1;
double sss=0,tj,mm=1e6;
for (j=1; j<=n; j++)
{
tj=d[j];
if(tj>ds)
{
flag=0;
break;
}
sss+=tj;
if(tj<mm)
mm=tj;
}
if(flag)
ans[cnt++]=info(i,sss/n,sss,mm);
}
if(cnt==0)
puts("No Solution");
else
{
sort(ans,ans+cnt,cmp);
printf("G%d\n%.1lf %.1lf\n",ans[0].s,ans[0].minm,ans[0].aver);
}
}
return 0;
}

最新文章

  1. [No00009F]CMD在执行命令时的中断快捷键
  2. c# 变量,对象,静态类型,集合类的线程安全回顾
  3. eclipse使用tomcat进行部署时编译代码不一致的处理
  4. 【JWPlayer】官方JWPlayer去水印步骤
  5. codevs 3290 华容道
  6. table_open_cache
  7. mysql事务回滚
  8. 使用 Azure Site Recovery 将内部部署虚拟化工作负荷迁移至 Azure
  9. Foundation Data Structure
  10. mysql版本问题sql_mode=only_full_group_by
  11. LINUX编程学习笔记(十三) 遍历目录的两种方法
  12. php intval()和floatval()
  13. Kafka 配置安装
  14. 08-DML(插入、更新、删除)
  15. tf.layers.dense()
  16. Methods to reduce the number of pipeline stages
  17. Oracle EBS AR 删除应收发票
  18. java-基础-【二】内部类与静态内部类
  19. 在Qt示例项目的C ++ / QML源中的//! [0]的含义是什么?
  20. win下如何解决在chrome的同源访问问题

热门文章

  1. VS2010每次编译都重新编译 解决方案
  2. fiddler+willow问题总结
  3. uvm_reg_field——寄存器模型(二)
  4. ThreadLocal应用场景以及源码分析
  5. HTML5文档结构 摘要
  6. 百度影棒安装apk方法
  7. Servlet Context
  8. git 添加 ,密匙
  9. java 操作mongodb查询条件的常用设置
  10. OJ 大整数减法