Luckies @ 2022-12-31 10:37:59
有没有用vector存图的啊,蒟蒻不会链式前向星
by Cerisier @ 2022-12-31 10:40:52
#include <cstring>
#include <iostream>
#include <queue>
#include <set>
#include <vector>
using namespace std;
const int maxn = 1e5 + 10;
int inf;
struct node {
int v, w;
node(int vv, int ww) { v = vv, w = ww; }
};
vector<node> g[maxn];
int d[maxn];
int n, m, s;
queue<int> q;
bool in_queue[maxn];
void spfa(int s) {
memset(d, 0x3f, sizeof(d));
inf = d[1];
d[s] = 0;
in_queue[s] = true;
q.push(s);
while (!q.empty()) {
int u = q.front();
q.pop();
in_queue[u] = false;
for (int i = 0; i < g[u].size(); i++) {
int v = g[u][i].v;
if (d[v] > d[u] + g[u][i].w) {
d[v] = d[u] + g[u][i].w;
if (!in_queue[v]) {
q.push(v);
}
}
}
}
}
set<pair<int, int> > min_heap;
void dij(int s) {
memset(d, 0x3f, sizeof(d));
inf = d[1];
d[s] = 0;
min_heap.insert(make_pair(d[s], s));
while (!min_heap.empty()) {
int mind = min_heap.begin()->first;
int u = min_heap.begin()->second;
min_heap.erase(min_heap.begin());
for (int i = 0; i < g[u].size(); i++) {
int v = g[u][i].v;
if (d[v] > d[u] + g[u][i].w) {
min_heap.erase(make_pair(d[v], v));
d[v] = d[u] + g[u][i].w;
min_heap.insert(make_pair(d[v], v));
}
}
}
}
int main() {
cin >> n >> m >> s;
for (int i = 1; i <= m; i++) {
int u, v, w;
cin >> u >> v >> w;
g[u].push_back(node(v, w));
}
dij(s);
for (int i = 1; i <= n; i++) {
if (d[i] == inf) {
cout << 2147483647 << ' ';
} else {
cout << d[i] << ' ';
}
}
return 0;
}
by Cerisier @ 2022-12-31 10:40:59
@Stephen__Curry
by joyslog @ 2022-12-31 10:41:54
完全可以用 std::vector
。
建边:
struct Edge {int u, v, w;};
vector<Edge> edges;
vector<int> G[MAX_N];
inline void AddEdge(int u, int v, int w) {
edges.push_back({u, v, w});
G[u].push_back(edges.size() - 1);
}
遍历:
for(int i = 0; i < G[u].size(); i++) {
int v = edges[G[u][i]].v, w = edges[G[u][i]].w;
虽然常数确实略大,但是没被卡过。
by scp020 @ 2022-12-31 10:49:32
dijkstra+堆优化,vector存图。
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
struct edge{int to,cost;};
vector<edge> g[200010];
int f[200010],v[200010],pos,n,m,s;
priority_queue< pair<int,int> > q;
void dijkstra(int s)
{
for(int i=1;i<=n;i++) f[i]=inf;
f[s]=0;
q.push(make_pair(0,s));
while(!q.empty())
{
pos=q.top().second,q.pop();
if(v[pos]) continue;
v[pos]=1;
for(int i=0,x,y;i<g[pos].size();i++)
{
x=g[pos][i].to,y=g[pos][i].cost;
if(f[x]>f[pos]+y) f[x]=f[pos]+y,q.push(make_pair(-f[x],x));
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&s);
for(int i=1,x,y,z;i<=m;i++) scanf("%d%d%d",&x,&y,&z),g[x].push_back((edge){y,z});
dijkstra(s);
for(int i=1;i<=n;i++) printf("%d ",f[i]);
return 0;
}
by ssilrrr @ 2022-12-31 11:25:30
一直用vector存图。
还有遍历的时候更方便的办法:直接存pair。
for(auto [v,w]:v[u])
by Luckies @ 2022-12-31 11:32:03
蟹蟹大家,我用vector存图一直过不了样例
by Luckies @ 2022-12-31 11:32:23
刚刚才过的
by Ruiqun2009 @ 2023-01-07 23:07:53
其实我写也是用结构化绑定+vector
存图+手写堆。
#include <cstdio>
#include <cctype>
#include <vector>
#include <cstring>
#include <utility>
#include <stdexcept>
#include <queue>
constexpr int MAXN = 100005;
template <size_t __length>
class my_bitset32 {
unsigned _M_arr[(__length + 31) >> 5] = {0};
static_assert(__length >= 1, "");
public:
inline _GLIBCXX14_CONSTEXPR my_bitset32(unsigned long long val = 0) noexcept {
if _GLIBCXX17_CONSTEXPR (__length >= 2) {
_M_arr[1] = val & ((1ull << 32ull) - 1ull);
_M_arr[0] = val >> 32ull;
}
else _M_arr[0] = val & ((1ull << 32ull) - 1ull);
}
class reference {
size_t _M_pos;
friend class my_bitset32<__length>;
unsigned* ptr;
inline _GLIBCXX_CONSTEXPR reference() {}
public:
reference(my_bitset32<__length>& b, size_t pos) noexcept {
_M_pos = pos & 31;
ptr = b._M_arr + (pos >> 5);
}
inline _GLIBCXX_CONSTEXPR operator bool() const noexcept { return (*(ptr) & (1 << _M_pos)) != 0; }
inline _GLIBCXX_CONSTEXPR bool operator~() const noexcept { return (*(ptr) & (1 << _M_pos)) == 0; }
inline _GLIBCXX14_CONSTEXPR reference& flip() noexcept {
*ptr ^= (1 << _M_pos);
return *this;
}
inline _GLIBCXX14_CONSTEXPR reference& operator=(bool v) noexcept {
if (v) *ptr |= (1 << _M_pos);
else *ptr &= ~(1 << _M_pos);
return *this;
}
~reference() {}
inline _GLIBCXX14_CONSTEXPR reference(const reference&) = default;
};
friend class reference;
public:
#if __cplusplus > 202002L
constexpr
#endif
inline reference operator[](size_t index) { return reference(*this, index); }
inline _GLIBCXX_CONSTEXPR bool operator[](size_t index) const { return (bool)reference(*this, index); }
inline _GLIBCXX_CONSTEXPR size_t size() const noexcept { return __length; }
inline size_t count() const noexcept {
size_t ans = 0;
for (size_t i = 0; i < ((__length + 31) >> 5); i++) ans += __builtin_popcount(_M_arr[i]);
return ans;
}
inline bool test(size_t pos) const {
if (pos >= size()) throw std::out_of_range("my_bitset32::test");
return this->operator[](pos);
}
inline bool all() const noexcept {
for (size_t i = 0; i < ((__length + 31) >> 5); i++) if (__builtin_popcount(_M_arr[i]) != 32) return false;
return true;
}
inline bool none() const noexcept {
for (size_t i = 0; i < ((__length + 31) >> 5); i++) if (__builtin_popcount(_M_arr[i]) != 0) return false;
return true;
}
inline bool any() const noexcept {
for (size_t i = 0; i < ((__length + 31) >> 5); i++) if (__builtin_popcount(_M_arr[i]) != 0) return true;
return false;
}
inline _GLIBCXX14_CONSTEXPR my_bitset32<__length>& operator&=(const my_bitset32<__length>& other) noexcept {
for (size_t i = 0; i < ((__length + 31) >> 5); i++) _M_arr[i] &= other._M_arr[i];
return *this;
}
inline _GLIBCXX14_CONSTEXPR my_bitset32<__length>& operator|=(const my_bitset32<__length>& other) noexcept {
for (size_t i = 0; i < ((__length + 31) >> 5); i++) _M_arr[i] |= other._M_arr[i];
return *this;
}
inline _GLIBCXX14_CONSTEXPR my_bitset32<__length>& operator^=(const my_bitset32<__length>& other) noexcept {
for (size_t i = 0; i < ((__length + 31) >> 5); i++) _M_arr[i] ^= other._M_arr[i];
return *this;
}
inline _GLIBCXX14_CONSTEXPR my_bitset32<__length> operator~() const noexcept {
my_bitset32<__length> res;
for (size_t i = 0; i < ((__length + 31) >> 5); i++) res._M_arr[i] = ~_M_arr[i];
for (size_t i = (__length & 31); i < 32; i++) res._M_arr[__length >> 5] &= ~(1 << i);
return res;
}
inline void reset() { memset(_M_arr, 0, ((__length + 31) >> 5) * sizeof(unsigned)); }
};
std::vector<std::pair<int, int> > e[MAXN];
int d[MAXN];
my_bitset32<MAXN> vis;
char c;
constexpr size_t READ_MAXN = 1 << 16;
constexpr size_t READ_ARR_SIZE = READ_MAXN | 5;
char inbuf[READ_ARR_SIZE], outbuf[READ_ARR_SIZE];
char *curinpos = inbuf + READ_MAXN, *curoutpos = outbuf;
char *end_inbuf = inbuf + READ_MAXN, *end_outbuf = outbuf + READ_MAXN;
inline char gc() {
if (curinpos == end_inbuf) {
end_inbuf = inbuf + fread(inbuf, 1, READ_MAXN, stdin);
curinpos = inbuf;
}
return *curinpos++;
}
inline void pc(char x) {
if (curoutpos == end_outbuf) {
fwrite(outbuf, 1, READ_MAXN, stdout);
curoutpos = outbuf;
end_outbuf = outbuf + READ_MAXN;
}
*curoutpos++ = x;
}
inline unsigned readuint() {
unsigned eax(0);
c = gc();
while (!isdigit(c)) c = gc();
while (isdigit(c)) eax = (eax << 3) + (eax << 1) + (c & 15), c = gc();
return eax;
}
inline void putuint(unsigned x) {
static char buf[15];
static unsigned curpos;
curpos = 0;
do {
buf[curpos++] = (x % 10) | 48;
x /= 10;
} while (x);
while (curpos--) pc(buf[curpos]);
}
std::pair<unsigned, unsigned> heap[MAXN];
unsigned tot = 0;
inline void my_swap(unsigned& a, unsigned& b) { a ^= b ^= a ^= b; }
inline void my_swap(std::pair<unsigned, unsigned>& a, std::pair<unsigned, unsigned>& b) {
my_swap(a.first, b.first);
my_swap(a.second, b.second);
}
inline void __push(unsigned pos = tot) {
while (pos > 1 && heap[pos] < heap[pos >> 1]) {
my_swap(heap[pos], heap[pos >> 1]);
pos >>= 1;
}
}
inline void __adjust(unsigned pos = 1) {
unsigned tar = pos << 1;
while (tar <= tot) {
if (tar < tot) tar = heap[tar] < heap[tar | 1] ? tar : (tar | 1);
if (heap[pos] > heap[tar]) my_swap(heap[pos], heap[tar]);
else break;
pos = tar;
tar = pos << 1;
}
}
inline void push(const std::pair<unsigned, unsigned>& x) {
heap[++tot] = x;
__push();
}
inline void pop() {
my_swap(heap[1], heap[tot--]);
__adjust();
}
inline void add(int u, int v, int w) { e[u].emplace_back(v, w); }
inline void dij(unsigned s) {
push(std::make_pair(0, s));
memset(d, 0x3f, MAXN * sizeof(unsigned));
vis.reset();
d[s] = 0;
while (tot) {
int u = heap[1].second;
pop();
if (vis[u]) continue;
vis[u] = true;
for (auto [v, w] : e[u]) if (d[v] > d[u] + w) {
d[v] = d[u] + w;
push(std::make_pair(d[v], v));
}
}
}
unsigned n, m, S;
void Read() {
n = readuint(), m = readuint(), S = readuint();
unsigned u, v, z;
for (unsigned i = 1; i <= m; i++) {
u = readuint(), v = readuint(), z = readuint();
add(u, v, z);
}
}
void Solve() {
dij(S);
for (unsigned i = 1; i <= n; i++) putuint(d[i] == 0x3f3f3f3f ? 2147483647 : d[i]), pc(' ');
}
int main() {
Read();
Solve();
fwrite(outbuf, 1, curoutpos - outbuf, stdout);
return 0;
}