团体程序设计天梯赛 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;
}
posted @ 2020-01-29 14:58  YuhanのBlog  阅读(234)  评论(0编辑  收藏  举报