目录
例题1-Wormhole Sort
农夫约翰的奶牛已经厌倦了他每天早上离开谷仓前要自己分类的要求。他们刚刚完成了量子物理学博士学位,并准备加快速度。
今天早上,像往常一样,Farmer John 的 N 头奶牛 (1≤N≤105),方便地编号为 1…N,分散在整个谷仓的 N 个不同位置,也编号为 1…N,因此奶牛 i 位于位置 pi。但是今天早上还有M个虫洞(1≤M≤105),编号为1…M,其中虫洞i双向连接位置ai和位置bi,宽度wi(1≤ai,bi≤N,ai≠bi, 1≤wi≤109)。
在任何时间点,位于虫洞两端的两只奶牛可能会选择同时通过虫洞交换位置。奶牛必须执行这种交换,直到奶牛 i 在位置 i 1≤i≤N。
奶牛并不急于被虫洞压扁。帮助他们最大化他们必须用来分类自己的最窄虫洞的宽度。保证奶牛可以自行分类。
思路
题目的大致意思就是要将数列排序,以非下降序列用权制排序。例如:
1 2 9 1 3 7 2 3 10 2 4 3
排序完后:
2 4 3 1 3 7 1 2 9 2 3 10
代码实现
C++代码中,使用vector和pair是最简单的方法。
vector<pair<int,pair<int,int>>> v;
vector其中有两对nested pairs
部分代码如下:
#include <bits/stdc++.h>
using namespace std;
#define f first
#define s second
int main() {
int M = 4;
vector<pair<int,pair<int,int>>> v;
for (int i = 0; i < M; ++i) {
int a,b,w; cin >> a >> b >> w;
v.push_back({w,{a,b}});
}
sort(begin(v),end(v));
for (auto e: v) cout << e.s.f << " " << e.s.s << " " << e.f << "\n";
}
或者使用vector套array:
int main() {
int M = 4;
vector<array<int,3>> v; // or vector<vector<int>>
for (int i = 0; i < M; ++i) {
int a,b,w; cin >> a >> b >> w;
v.push_back({w,a,b});
}
sort(begin(v),end(v));
for (auto e: v) cout << e[1] << " " << e[2] << " " << e[0] << "\n";
}
比较函数
比较器所做的是比较两个对象,如下所示,基于我们的比较标准:
- 如果对象 x 小于对象 y,则返回 true
- 如果对象 x 大于或等于对象 y,则返回 false
方法1
#include <bits/stdc++.h>
using namespace std;
struct Edge {
int a,b,w;
bool operator<(const Edge& y) { return w < y.w; }
};
int main() {
int M = 4;
vector<Edge> v;
for (int i = 0; i < M; ++i) {
int a,b,w; cin >> a >> b >> w;
v.push_back({a,b,w});
}
sort(begin(v),end(v));
for (Edge e: v) cout << e.a << " " << e.b << " " << e.w << "\n";
}
方法2
#include <bits/stdc++.h>
using namespace std;
struct Edge {
int a,b,w;
};
bool cmp(const Edge& x, const Edge& y) { return x.w < y.w; }
int main() {
int M = 4;
vector<Edge> v;
for (int i = 0; i < M; ++i) {
int a,b,w; cin >> a >> b >> w;
v.push_back({a,b,w});
}
sort(begin(v),end(v),cmp);
for (Edge e: v) cout << e.a << " " << e.b << " " << e.w << "\n";
}