团体程序设计天梯赛 L3-005 垃圾箱分布 (30分)(Djikstra求最短路)
题目链接:
L3-005 垃圾箱分布 (30分)
思路:
按题意用Dijkstra求得每个垃圾箱到所有居民的最短路径,这些最短路里最短的一个就是垃圾箱到所有居民的最短路,此时我们求得所有垃圾箱里这个最短路最长的一个即可;
如果存在距离大于Ds的要舍去,得到多个答案需要按题意筛选出唯一的一个输出;
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1234;
const int INF = 1 << 30;
typedef pair<int, int> P;
struct edge { int to, cost; };
vector<edge> G[maxn];
int n, m, k, ds, d[maxn];
struct node {
int d, no, tot;
bool operator < (const node & a ) const {
if(d != a.d) return d > a.d;
return tot == a.tot ? no < a.no : tot < a.tot;
}
};
vector<node> res;
void dijkstra(int s) {
fill(d, d + n + m + 1, INF);
d[s] = 0;
priority_queue<P, vector<P>, greater<P> > que;
que.push(P{0, s});
while(!que.empty()) {
P p = que.top();
que.pop();
int v = p.second;
if(d[v] < p.first) continue;
for(edge & e : G[v]) if(d[e.to] > d[v] + e.cost) {
d[e.to] = d[v] + e.cost;
que.push(P{d[e.to], e.to});
}
}
int _d = INF, _tot = 0;
for(int i = 1; i <= n; i++) {
if(d[i] > ds) return;
_d = min(_d, d[i]);
_tot += d[i];
}
res.push_back(node{_d, s - n, _tot});
}
#define getno(s) (s[0] == 'G' ? stoi(s.substr(1)) + n : stoi(s))
int main() {
#ifdef MyTest
freopen("Sakura.txt", "r", stdin);
#endif
cin >> n >> m >> k >> ds;
for(int i = 0; i < k; i++) {
string s1, s2;
int dis;
cin >> s1 >> s2 >> dis;
int x = getno(s1), y = getno(s2);
G[x].push_back(edge{y, dis});
G[y].push_back(edge{x, dis});
}
for(int i = 1; i <= m; i++) dijkstra(i + n);
if(res.size() == 0) { puts("No Solution"); return 0; }
sort(res.begin(), res.end());
printf("G%d\n%.1f %.1f", res[0].no, 1.0 * res[0].d, res[0].tot * 1.0 / n);
return 0;
}