最近开始复习NOIP2019,又刷了一遍前几年的题,感触很深,2017年Day1T3绝对是一道好题,考察的方面非常得广,值得发篇题解供大家参考一下。
PART1(输入——存图):
个人比较喜欢链式前向星的存图方法,非常简便,不多说了,上代码:
struct Edge {
int u, v, w, next;
};
Edge e[maxm * 2];
void addEdge(int u, int v, int w) {
en ++;
e[en].v = v;
e[en].w = w;
e[en].next = head[u];
head[u] = en;
}
int main() {
int t;
en = 0;
cin >> t;
while (t--) {
en = 0;
cin >> n >> m >> K >> p;
for (int i = 1; i <= n; ++i) head[i] = 0;
for (int i = 1; i <= m; ++i) {
int u, v, w;
cin >> u >> v >> w;
addEdge(u, v, w);
}
}
return 0;
}
Part2(求最短路径):
分析一下这道题,明显要求一遍最短路径,而且最好把从1开始到每个点的最短路径存下来,备之后只用。笔者用的是dijsktra算法+堆优化,是最短路径求法中较快的,也是十分稳定的一种算法(SPFA容易被卡常数)也非常常规:
typedef pair<int,int> state;
void dijkstra(int s) {
for (int i = 1; i <= n; ++i) vs[i] = false;
for (int i = 1; i <= n; ++i) d[i] = INT_MAX;
d[s] = 0;
priority_queue<state, vector<state>, greater<state> > q;
q.push(make_pair(0, s));
while (!q.empty()) {
state k = q.top();
q.pop();
if (vs[k.second]) continue;
vs[k.second] = true;
int u = k.second;
for (int num = head[u]; num != 0; num = e[num