中国矿业大学数据结构实验(4)

A 机器人王国的路径长度
题目描述

在一个机器人王国里,围绕首都分\(N\)层构建卫星城市。以首都为圆心,以路相连分出两个卫星城在第一个层,然后每个卫星城又有路相连分出两个卫星城在下一层,但每条路的长度不同。第\(N\)层的卫星城不再分出新的卫星城。现在人类只探知到所有直接相连的城市间的路程,你能计算某个卫星城到达首都的路程吗?

输入

第一行为\(N\),表示机器人王国里有\(N\)层卫星城,\(N\)最大为10。从第二行开始,共\(2^{N+1}-2\)行,每行分别是城市的代号到其分出的卫星城的代号和它们间的路程。 代号用若干个字母表示,直连路程最大为100。最后一行是某卫星城的代号。

输出

根据最后一行的卫星城代号,求该卫星城到首都的路程。

样例输入
2
A F 20
B D 100
G A 5
G B 10
A C 6
B E 30
D
样例输出
110
思路

建模:给你一颗\(N\)层完全二叉树,根节点已知(可以设为\(-1\)),求根到给定节点的路径长

需要记录两个信息:节点\(u\)的父亲\(fa\),边权\((u,fa)\),开一个结构体即可

struct edge
{
	int fa;//父亲节点
    int w; //边权
}
ACcode
#include<iostream>
#include<cmath>
using namespace std;
const int N = 15;
struct edge
{
	int fa = -1,w;
}e[10000];
int toi(char c) { return c - 'A' + 1; }


int main()
{
	int n, m;
	cin >> n;
	m = pow(2, n + 1) - 2;
	cout << m << endl;
	for (int i = 1; i <= m; i++)
	{
		int w;
		char a, b;
		cin >> a >> b >> w;
		int u = toi(a), v = toi(b);
		e[v] = { u,w };
	}
	int q, ans = 0;
	char c; cin >> c;
	q = toi(c);
	while (q != -1)
	{
		ans += e[q].w;
		q = e[q].fa;
	}
	cout << ans << endl;

	return 0;
}
B 从源点开始的最短路径
题目描述

给你一个有向图的所有顶点有序对,顶点用\(1-n\)编号,每个有序对描述有向边,请编程求解从1到任意一个顶端\(i\)的最短路径长度。

输入

第一行是\(n\)\(m\),分别表示顶点数\((n<100)\)和有向边数\((m<100)\)
从第二行开始\(m\)行,对应三个数,前两个表示顶点有序对,第三个数表示边的权。
最后一行\(i\),表示要求解从1到顶点\(i\)的最短路径长度。

输出

从1到顶点\(i\)的最短路径长度。

样例输入
4 5
1 2 4
1 3 6
2 3 1
3 4 6
2 4 7
3
样例输出
5
思路

纯模板不解释

ACcode
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int N = 105;
const int inf = 0x3f3f3f3f;
struct edge {
	int v, w;
};
vector<edge>e[N];
int n, m, a, b, c;
int d[N], vis[N];

void dijkstra(int s)
{
	for (int i = 1; i <= n; i++) d[i] = inf;
	d[s] = 0;
	priority_queue<pair<int, int>>q;
	q.push({ 0,s });
	while (q.size())
	{
		auto t = q.top(); q.pop();
		int u = t.second;
		if (vis[u]) continue;
		vis[u] = 1;
		for (auto ed : e[u])
		{
			int v = ed.v, w = ed.w;
			if (d[u] + w < d[v])
			{
				d[v] = d[u] + w;
				q.push({ -d[v],v });
			}
		}
	}
}


int main()
{
	cin >> n >> m;
	for (int i = 1; i <= m; i++)
	{
		cin >> a >> b >> c;
		e[a].push_back({ b,c });  //有向图
	}
	dijkstra(1);
	int i; cin >> i;
	cout << d[i] << endl;

	return 0;
}
C 最少天数
问题描述

现有一个工程项目,包含多个子任务。每个子任务有明确的前置任务和完成所需的天数。项目的开始节点为 A,结束节点为 Z。请计算完成整个工程所需的最短天数。

输入格式
  • 第一行包含两个整数 NM,分别表示项目中的节点数(事件数)和子任务数。
  • 接下来的 M 行,每行包含三个信息:startNode endNode weight,表示从节点 startNode 到节点 endNode 的子任务需要 weight 天完成。
输出格式

输出一个整数,表示完成整个工程所需的最短天数。

样例输入
6 8  
A B 3  
A C 2  
B D 2  
B E 3  
C E 4  
D F 3  
E F 2  
F Z 1  
样例输出
9  
思路

在DAG上拓扑排序,同时\(dp\),状态转移\(dp[u]=\max\{dp[v_i]+w(v_i,u)\}\)

ACcode
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
const int N = 1000;
struct edge
{
	int v, w;
};
vector<edge> e[N];
int dp[N], din[N], vis[N];
int n, m, c;
char a, b;
int toi(char c) { return c - 'A' + 1; }

void topo(int s)
{
	memset(dp, 0, sizeof dp);
	queue<int> q;
	q.push(s);
	while (q.size())
	{
		int u = q.front();
		q.pop();
		for (auto ed : e[u])
		{
			int v = ed.v, w = ed.w;
			din[v]--;
			dp[v] = max(dp[v], dp[u] + w);
			if (!din[v]) q.push(v);
		}
	}
}


int main()
{
	cin >> n >> m;
	for (int i = 1; i <= m; i++)
	{
		cin >> a >> b >> c;
		int u = toi(a), v = toi(b);
		e[u].push_back({ v,c });
		din[v]++;
	}

	topo(1);
	cout << dp[toi('Z')];

	return 0;
}

D 寻找第二小的数

题目描述

\(n\)个整数中第二小的数。
相同的整数看成一个数。比如,有5个数分别是1,1,3,4,5,那么第二小的数就是3。

输入

输入包含多组测试数据。输入的第一行是一个整数C,表示有C组测试数据;
每组测试数据的第一行是一个整数n,表示本组测试数据有n个整数(2<=n<=10),接着一行是n个整数(每个数均小于100)。

输出

为每组测试数据输出第二小的整数,如果不存在第二小的整数则输出“NO”,每组输出占一行。

样例输入
3
2
1 2
5
1 1 3 4 5
3
1 1 1
样例输出
2
3
NO
ACcode
#include<bits/stdc++.h>
using namespace std;
const int N = 100;
int n,T,a[N];

int main()
{
	cin >> T;
	while(T--)
	{
		cin >> n;
		for(int i = 1 ; i <= n ; i ++) cin >> a[i];
		sort(a+1,a+n+1);
		int t = a[1];
		int rk = 1;
		while(a[rk] == t && rk < n) rk ++;
		if(a[rk] == t) cout << "NO" << endl;
		else cout << a[rk] << endl;
	}
	
	return 0;
}

E 按十进制各位和排序

题目描述

对于给定的正整数序列,按照每个数的十进制形式各个位上的数之和从大到小排序,各个位上的数和相同的按照本身大小排序,大的在前,小的在后。

输入

第一行 1 个整数 n,表示序列的大小。( 0 < n ≤ 1000) 第二行 n 个正整数,表示序列的每个数,每个数不大于 100000000。

输出

输出按照题目要求排序后的序列。

样例输入
6 
17 26 9 13 88 22
样例输出
88 9 26 17 22 13
ACcode
#include<bits/stdc++.h>
using namespace std;
const int N = 1005;
string a[N];
int n;

bool cmp(string a,string b)
{
	int sum1 = 0 ,sum2 = 0;
	for(int i = 0 ; i < a.size() ; i ++) sum1 += (a[i]-'0');
	for(int i = 0 ; i < b.size() ; i ++) sum2 += (b[i]-'0');
	if(sum1 != sum2) return sum1 > sum2;
	else
	{
		if(a.size() != b.size()) return a.size() > b.size();
		for(int i = 0 ; i < a.size(); i ++)
		{
			if(a[i] != b[i]) return a[i] > b[i];
		}
		return true;
	} 
}

int main()
{
	cin >> n;
	for(int i = 1 ; i <= n ; i ++) cin >> a[i];
	sort(a+1,a+n+1,cmp);
	for(int i = 1 ; i <= n ; i ++) cout << a[i] << " ";
	
	return 0;
}
posted @ 2025-06-24 13:03  _P_D_X  阅读(71)  评论(0)    收藏  举报