week9

第一题

单向图。用的邻接表存的图之后再接一个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] << " ";
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值