建图,最短路
题意:
分析:
没有什么难以思考的地方,关键就是建图,我们以每个机场为节点建图。成功建图后跑4次dijstra算法
取得城市a到城市b的最小路径就行了。
但是,在此题中建图这件事还真是挺大工程的。代码量巨大,烦死我了。
代码如下:
#include<iostream> #include<algorithm> #include<vector> #include<queue> #include<functional> #include<iomanip> using namespace std; const int max_n = 410*5; const double inf = 1e18; typedef pair<double, int> pdi; struct node { double x, y;int num; }; struct edge{int to;double cost;}; vector<edge> G[max_n]; vector<node> ns; double d[max_n]; int n, air, a, b; void init() { for (int i = 0;i <= n * 5 + 10;i++)G[i].clear(); ns.clear(); } void dijstra(int s) { fill(d, d + n * 5, inf); priority_queue<pdi, vector<pdi>, greater<pdi>> que; d[s] = 0;que.push({ d[s], s }); while (!que.empty()) { pdi p = que.top();que.pop(); if (p.first > d[p.second])continue; d[p.second] = p.first; for (int i = 0;i < G[p.second].size();i++) { edge& e = G[p.second][i]; if (d[e.to] < p.first + e.cost)continue; d[e.to] = p.first + e.cost; que.push({ d[e.to],e.to }); } } } double computdist(node n1,node n2) { return sqrt((n1.x - n2.x) * (n1.x - n2.x) + (n1.y - n2.y) * (n1.y - n2.y)); } void deal(node& n1,node& n2,node& n3,node& n4,double road) { double len1, len2, len3; len1 = computdist(n1, n2); len2 = computdist(n1, n3); len3 = computdist(n2, n3); G[n1.num].push_back({ n2.num,road * len1 }); G[n2.num].push_back({ n1.num,road * len1 }); G[n1.num].push_back({ n3.num,road * len2 }); G[n3.num].push_back({ n1.num,road * len2 }); G[n2.num].push_back({ n3.num,road * len3 }); G[n3.num].push_back({ n2.num,road * len3 }); if (len1 >= len2 && len1 >= len3) { n4.x = n1.x + n2.x - n3.x; n4.y = n1.y + n2.y - n3.y; } else if (len2 >= len1 && len2 >= len3) { n4.x = n1.x + n3.x - n2.x; n4.y = n1.y + n3.y - n2.y; } else { n4.x = n2.x + n3.x - n1.x; n4.y = n2.y + n3.y - n1.y; } G[n4.num].push_back({ n3.num,len1 * road }); G[n3.num].push_back({ n4.num,len1 * road }); G[n4.num].push_back({ n1.num,len3 * road }); G[n1.num].push_back({ n4.num,len3 * road }); G[n4.num].push_back({ n2.num,len2 * road }); G[n2.num].push_back({ n4.num,len2 * road }); } int main() { ios::sync_with_stdio(0); int t;cin >> t; while (t--) { cin >> n >> air >> a >> b; init();int total = 0; for (int i = 1;i <= n;i++) { vector<node> nn(4);double road; cin >> nn[0].x >> nn[0].y >> nn[1].x >> nn[1].y >> nn[2].x >> nn[2].y >> road; nn[0].num = ++total;nn[1].num = ++total;nn[2].num = ++total;nn[3].num = ++total; deal(nn[0], nn[1], nn[2], nn[3], road); for (int j = 0;j < ns.size();j++) { node& cur = ns[j]; for (int k = 0;k < 4;k++) { double dist = computdist(cur, nn[k]); G[cur.num].push_back({ nn[k].num,dist * air }); G[nn[k].num].push_back({ cur.num,dist * air }); } }while (!nn.empty()) { ns.push_back(nn.back()); nn.pop_back(); } } double ans = inf; for (int i = 1;i <= 4;i++) { dijstra(4 * a - 4 + i); for (int j = 1;j <= 4;j++) ans = min(ans, d[4 * b - 4 + j]); } cout << fixed << setprecision(1) << ans << endl; } }
看别的题解,代码似乎精简许多?!不说了,去学习