第一题
单向图。用的邻接表存的图之后再接一个dfs和bfs板子。
#include<bits/stdc++.h>
using namespace std;
int n, m;
vector <int> map1[100000];
int again[100000];
void dfs(int x) {
if (again[x] == 1)return;
cout << x<<" ";
again[x] = 1;
if ((int)map1[x].size() > 0) {
for (int i = 0; i < (int)map1[x].size(); i++) {
dfs(map1[x][i]);
}
}
}
void bfs(int x) {
queue <int> dui;
dui.push(x);
again[x] = 1;
while (!dui.empty()) {
int temp = dui.front();
dui.pop();
cout << temp << " ";
for (int i = 0; i < (int)map1[temp].size(); i++) {
if (again[map1[temp][i]] == 0) {
dui.push(map1[temp][i]);
again[map1[temp][i]] = 1;
}
}
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int s, e;
cin >> s >> e;
map1[s].push_back(e);
}
for (int i = 1; i <= n; i++) {
sort(map1[i].begin(), map1[i].end());
}
dfs(1);
cout << endl;
memset(again, 0, sizeof(again));
bfs(1);
}
第二题
什么神奇的东西,卡了半天最后发现给读入加个min(l,f[s][e])就过了,怀疑是一条边有多个权值。。。。。。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 0x3f3f3f3f;
int n, m;
int f[1000][1000];
const int mod = 998244354;
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
f[i][j] = maxn;
f[i][i] = 0;
}
}
for (int i = 0; i < m; i++) {
int s, e, l;
cin >> s >> e >> l;
f[s][e] = min(l,f[s][e]);
f[e][s] = min(l,f[e][s]);
}
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
}
}
}
for (int i = 1; i <= n; i++) {
long long sum = 0;
for (int j = 1; j <= n; j++) {
sum = (f[i][j]+sum)%mod;
}
cout << sum << endl;
}
}
第三题
基本就是按照讲的写的
重复n-1次,每找到一个最小点就标记,并且更新其周围的点。
ver1.0
用堆优化了速度,最开始,除了s以外的dis都是无穷,因为更新,所以才有节点变小,因此我们可以定义个len的小顶堆,每更新一次塞一个节点进去。但由于塞进去的节点再之后可能会被更新,所以如果取出来的节点和现在的dis不一样,就continue再来一轮
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
struct edge
{
int end, len;
};
struct cmp
{
bool operator ()(const edge a, const edge b) {
return a.len > b.len;
}
};
vector <edge> map1[100010];
int dis[100010];
int n, m, s;
int again[100010];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> s;
for (int i = 1; i <= m; i++) {
int st, en, le;
cin >> st >> en >> le;
map1[st].push_back({ en,le });
}
priority_queue<edge, vector<edge>, cmp> dui;
memset(dis, 0x3f3f3f3f, sizeof(dis));
dis[s] = 0;
dui.push({ s,0 });
while (!dui.empty()) {
int en = dui.top().end;
int le = dui.top().len;
dui.pop();
if (dis[en] != le)continue;
again[en] = 1;
for (int i = 0; i < map1[en].size(); i++) {
if (again[map1[en][i].end])continue;
dis[map1[en][i].end] = min(dis[map1[en][i].end], dis[en] + map1[en][i].len);
dui.push({ map1[en][i].end,dis[map1[en][i].end] });
}
}
for (int i = 1; i <= n; i++) {
cout << dis[i] << " ";
}
}