并查集、最短路

并查集:

https://www.starrycoding.com/problem/68

// Problem: ${json.name}
// Contest: ${json.group}
// URL: ${json.url}
// Memory Limit: ${json.memoryLimit} MB
// Time Limit: ${json.timeLimit} ms
// More thought is needed

#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 2e5 + 9;
int pre[N];  //用来说明下一个节点指向
int Hash[N];
int root(int i) {
  return pre[i] = (pre[i] == i ? i : root(pre[i]));
}  // root数组用来找到输入节点的root节点
void merge(int u, int v) { pre[root(u)] = root(v); }  //用于将u节点连接到v节点上
void solve() {
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= n; i++) pre[i] = i;  //将每个节点初始化为pre指向自己
  for (int i = 1; i <= m; i++) {
    int u, v;
    cin >> u >> v;
    merge(u, v);
  }
  for (int i = 1; i <= n; i++) {
    Hash[root(i)]++;  //桶存储
  }
  vector<int> vec;
  for (int i = 1; i <= n; i++) {
    if (Hash[i]) vec.push_back(Hash[i]);  //存到vec中
  }
  sort(vec.begin(), vec.end());
  for (auto& i : vec) {
    cout << i << " ";
  }
}

signed main() {
  ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  solve();
  return 0;
}

最短路:

https://www.starrycoding.com/problem/69

// Problem: ${json.name}
// Contest: ${json.group}
// URL: ${json.url}
// Memory Limit: ${json.memoryLimit} MB
// Time Limit: ${json.timeLimit} ms
// More thought is needed

#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;

const int N = 1e3 + 9;
int n, m;
struct Edge {  //自定义类型edge用于存储节点的指向节点和路径价值
  int out, value;
};
bitset<N> vis;  // vis做标记
int d[N];       // d数组存储最短路径
vector<Edge> node[N];  //生成edge类型数组,用于存储节点的入,出,价值,有点像桶
void dijkstra(int x) {
  memset(d, 0x3f,
         sizeof(int) * (n + 1));  //设d数组初值为0x3f,使其在下文的比较中覆盖
  d[x] = 0;                       //最初节点的价值为0
  for (int i = 1; i <= n; i++) {  //对所有节点遍历
    int u = 1;
    for (int j = 1; j <= n; j++) {  //寻找最小点
      if (vis[u] || (!vis[j] && d[j] < d[u])) u = j;
    }
    vis[u] = true;                  //标记为true
    for (auto& [v, w] : node[u]) {  //在最小点中找各路径,并计算各路径的价值
      if (!vis[v] && d[v] > d[u] + w) d[v] = d[u] + w;
    }
  }
}

void solve() {
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    node[u].push_back({v, w});
  }
  dijkstra(1);
  if (d[n] >= 0x3f3f3f3f3f3f) {
    cout << "-1";
  } else
    cout << d[n];
}

signed main() {
  ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  solve();
  return 0;
}

https://www.starrycoding.com/problem/70

// Problem: ${json.name}
// Contest: ${json.group}
// URL: ${json.url}
// Memory Limit: ${json.memoryLimit} MB
// Time Limit: ${json.timeLimit} ms
// More thought is needed

#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;

const int N = 2e5 + 9;
int n, m;
struct Edge {  //自定义类型edge用于存储节点的指向节点和路径价值
  int out, value;
  bool operator<(const Edge& v) const {  //自定义运算符
    return value == v.value ? out < v.out : value > v.value;
  }
};
bitset<N> vis;  // vis做标记
int d[N];       // d数组存储最短路径
vector<Edge> node[N];  //生成edge类型数组,用于存储节点的入,出,价值,有点像桶
void dijkstra(int x) {
  memset(d, 0x3f,
         sizeof(int) * (n + 1));  //设d数组初值为0x3f,使其在下文的比较中覆盖
  d[x] = 0;                       //最初节点的价值为0
  priority_queue<Edge> pq;  //用快速队列(堆)来存储,自带维护,小顶堆
  pq.push({x, d[x]});       //先把x存入
  while (
      pq.size()) {  //其实都是一个东西,只是因为小顶堆自带维护功能,代替其挨个找最小
    int a = pq.top().out;
    pq.pop();
    if (vis[a]) continue;
    vis[a] = true;
    for (auto& [y, w] : node[a]) {
      if (!vis[y] && d[y] > d[a] + w) {  //判断
        d[y] = d[a] + w;
        pq.push({y, d[y]});  //压入
      }
    }
  }
}

void solve() {
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    node[u].push_back({v, w});
  }
  dijkstra(1);
  if (d[n] >= 0x3f3f3f3f3f3f) {
    cout << "-1";
  } else
    cout << d[n];
}

signed main() {
  ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  solve();
  return 0;
}

https://www.starrycoding.com/problem/71

  // Problem: ${json.name}
// Contest: ${json.group}
// URL: ${json.url}
// Memory Limit: ${json.memoryLimit} MB
// Time Limit: ${json.timeLimit} ms
// More thought is needed

#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 3e2 + 9;
int node[N][N];  //因为是单向节点,用于存储一个节点到另一个节点的价值
void solve() {
  int n, m, q;
  cin >> n >> m >> q;
  memset(node, 0x3f, sizeof node);
  for (int i = 1; i <= m; i++) {  //存入
    int u, v, w;
    cin >> u >> v >> w;
    node[u][v] = min(node[u][v], w);
  }
  for (int i = 1; i <= n; i++) {  //自己指向自己的价值为0
    node[i][i] = 0;
  }
  for (int k = 1; k <= n; k++) {  //背下来即可
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) {
        node[i][j] = min(node[i][j], node[i][k] + node[k][j]);
      }
    }
  }
  while (q--) {
    int u, v;
    cin >> u >> v;
    cout << (node[u][v] >= 4e18 ? -1 : node[u][v]) << endl;
  }
}

signed main() {
  ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  solve();
  return 0;
}

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部