vector有必要会吗?你真的会用吗?通过一道题来看看~

目录

简单明了的比较

看看代码

为什么这么好?

对vector的理解


杂务 - 洛谷

这道题用拓扑排序,但是在建图的时候,用领接矩阵很可能会TML,所以用领接表。

偷偷告诉你,如果硬要用领接矩阵,定义一个bool类型的二维数组建图就不会TML啦。

咳咳,来看下面

简单明了的比较

自己写领接表,写那堆函数

用vector

你看看这时间和空间,用vector都要优于不用

看看代码

不用的

#include<iostream>
#include<queue>
#include<algorithm>
#define ll long long
using namespace std;
const int N = 10002;
int n;
int num[N],in[N],f[N];
//in是入度  指进来   
queue<int>s;
ll ans=0;
ll max(ll x, int y) {
	return x > y ? x : y;
}
typedef struct node {
	int y;
	struct node* next;
}node;
typedef struct list {
	int head;
	node* n;
}list;
list g[N];
void init() {
	for (int i = 1; i <= n; i++) {
		g[i].head = i;
		g[i].n = nullptr;
	}
}
void insert(int i) {
	int c;
	while (cin >> c) {
		if (c == 0) {
			return;
		}
		node* new_ = new node;
		new_->y = i;
		new_->next = g[c].n;
		g[c].n = new_;
	}
}
int find(int m,int j) {
	node* a = g[m].n;
	while (a != nullptr) {
		if (a->y == j) {
			return 1;
		}
		a = a->next;
	}
	return 0;
}
int main()
{
	cin >> n;
	init();                       //初始化
	for (int i = 1; i <= n; i++) {   //插入
		int a, b, c;
		cin >> a >> b;
		num[a] = b;
		insert(a);
	}
	for (int i = 1; i <= n; i++) {   
		if (in[i]==0) {
			s.push(i);
			f[i] = num[i];
		}
	}
	while (!s.empty()) {    //拓扑
		int m = s.front();
		s.pop();
		for (int j = 1; j <= n; j++) {
			if (find(m,j)) {
				in[j]--;
				if (in[j] == 0)s.push(j);
				f[j] = max(f[j], f[m] + num[j]);
				ans = max(ans, f[j]);
			}
		}
	}
	cout << ans;
	return 0;
}

用了的

#include<iostream>
#include<queue>
#include<algorithm>
#include<vector>
#define ll long long
using namespace std;
const int N = 10002;
int n;
int num[N],in[N],f[N];
//in是入度  指进来   
queue<int>s;
vector<int>to[N];
ll ans=0;
ll max(ll x, int y) {
	return x > y ? x : y;
}
int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++) {
		int a, b, c;
		cin >> a >> b;
		num[a] = b;
		while (cin >> c) {
			if (c == 0)break;
			to[c].push_back(a);
			in[a]++;
		}
	}
	for (int i = 1; i <= n; i++) {
		if (in[i]==0) {
			s.push(i);
			f[i] = num[i];
		}
	}
	while (!s.empty()) {
		int now = s.front();
		s.pop();
		
		for (int j = 0; j < to[now].size(); j++) {
			int cnt = to[now][j];
			f[cnt] = max(f[cnt], f[now] + num[cnt]);
			ans = max(ans, f[cnt]);
			in[cnt]--;
			if (in[cnt] == 0)s.push(cnt);
			
		}
	}
	cout << ans;
	return 0;
}

怎么样,一下子简洁太多了,对吧,还很简单

为什么这么好?

vector源代码放这里了

https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/stl_vector.h

我看了看,哈哈,难搞——

直接说明原因吧

对于下面的第一点和第二个点,我们每次分配内存,一个一个new,浪费时间,而假如我一次new要一堆,我们要知道,new运算符首先在堆区分配足够的内存快,接着调用构造函数,我可以一次性调用构造函数来初始化,这是其一。内存对齐: 分配多个对象时,编译器可能会更好地管理内存对齐,从而减少内存浪费。这是其二。

  1. 内存分配策略: std::vector 在进行内存分配时,通常会分配一块稍微比当前大小大一些的内存,以便能够容纳未来的元素插入。这避免了每次插入元素都要重新分配内存的情况,从而提高了性能。

  2. 连续内存存储: std::vector 使用连续的内存块存储元素,这可以提供更好的缓存局部性,从而减少访问内存的开销。相比之下,链式结构的邻接表需要更多的内存以存储指针。

  3. 访问时间复杂度: 使用 std::vector 的直接索引访问元素的时间复杂度是 O(1),而在链表中查找元素需要线性时间,因此在寻找邻接节点时 std::vector 更高效。

  4. 空间效率: 由于使用 std::vector 的数据结构是紧凑的连续内存块,相对于链式结构的邻接表,它不需要额外的指针和链表节点开销,因此可能更加节省空间。

对vector的理解

std::vector 就是在数组的基础上进行了封装,使其具有了动态大小的能力。它可以看作是动态数组,因为它使用数组的连续内存存储和随机访问的优势,同时又能够在需要时自动扩展内存,实现动态的插入和删除。

与链表不同的是,std::vector 的内部实现并不是用指针来连接节点,而是通过动态调整数组的大小和复制元素来实现插入和删除。这使得 std::vector 在随机访问上更为高效,但在插入和删除方面可能相对较慢。

至于语法,这里就不过多赘述了——

有机会还是啃啃源代码了

下面是chatGPT给的简单的实现

#include <iostream>
#include <stdexcept>

template <typename T>
class Vector {
private:
    T* arr;
    size_t size;
    size_t capacity;

public:
    Vector() : arr(nullptr), size(0), capacity(0) {}

    Vector(size_t initialSize) : arr(new T[initialSize]), size(0), capacity(initialSize) {}

    ~Vector() {
        delete[] arr;
    }

    void push_back(const T& value) {
        if (size == capacity) {
            resize(capacity * 2 + 1);
        }
        arr[size++] = value;
    }

    T& at(size_t index) {
        if (index >= size) {
            throw std::out_of_range("Index out of range");
        }
        return arr[index];
    }

    size_t getSize() const {
        return size;
    }

    size_t getCapacity() const {
        return capacity;
    }

private:
    void resize(size_t newSize) {
        T* newArr = new T[newSize];
        for (size_t i = 0; i < size; ++i) {
            newArr[i] = arr[i];
        }
        delete[] arr;
        arr = newArr;
        capacity = newSize;
    }
};

int main() {
    Vector<int> vec;
    vec.push_back(10);
    vec.push_back(20);
    vec.push_back(30);

    for (size_t i = 0; i < vec.getSize(); ++i) {
        std::cout << vec.at(i) << " ";
    }

    return 0;
}

现在的我就是,看不见代码实现,我就难受哈哈哈哈

祝AC,拜拜~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

amojiacoco

请我杯饮料吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值