-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathGraphTemplate.cpp
118 lines (113 loc) · 3.69 KB
/
GraphTemplate.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
struct WeightedEdge{
ll to, cost;
WeightedEdge(){}
WeightedEdge(ll to, ll cost): to(to), cost(cost){}
operator ll() const { return to; }
};
struct WeightedGraph{
using E = WeightedEdge;
vector<vector<E>> g;
WeightedGraph(){}
WeightedGraph(ll n): g(n){}
vector<E>& operator[](ll at){ return g[at]; }
operator vector<vector<E>>&(){ return g; }
auto begin() const { return g.cbegin(); }
auto end() const { return g.cend(); }
ll size() const { return g.size(); }
const vector<E>& operator[](ll at) const { return g[at]; }
operator const vector<vector<E>>&() const { return g; }
void resize(ll a){ g.resize(a); }
void add_edge(ll a, ll b, ll cost){
g[a].emplace_back(b, cost);
g[b].emplace_back(a, cost);
}
void add_directed_edge(ll from, ll to, ll cost){
g[from].emplace_back(to, cost);
}
template<ll start_index = 1, bool directed = false> void input_graph(ll m){
while(m--){
ll a, b, c;
scanf("%lld%lld%lld", &a, &b, &c);
a -= start_index;
b -= start_index;
g[a].emplace_back(b, c);
if(!directed) g[b].emplace_back(a, c);
}
}
template<ll start_index = 1> void input_tree(ll n){ input_graph<start_index>(n - 1); }
};
struct UnWeightedEdge{
ll to;
static constexpr ll cost = 1;
UnWeightedEdge(){}
UnWeightedEdge(ll to): to(to){}
operator ll() const { return to; }
};
struct UnWeightedGraph{
using E = UnWeightedEdge;
vector<vector<E>> g;
UnWeightedGraph(){}
UnWeightedGraph(ll n): g(n){}
vector<E>& operator[](ll at){ return g[at]; }
operator vector<vector<E>>&(){ return g; }
auto begin() const { return g.cbegin(); }
auto end() const { return g.cend(); }
ll size() const { return g.size(); }
const vector<E>& operator[](ll at) const { return g[at]; }
operator const vector<vector<E>>&() const { return g; }
void resize(ll a){ g.resize(a); }
void add_edge(ll a, ll b){
g[a].emplace_back(b);
g[b].emplace_back(a);
}
void add_directed_edge(ll from, ll to){
g[from].emplace_back(to);
}
template<ll start_index = 1, bool directed = false> void input_graph(ll m){
while(m--){
ll a, b;
scanf("%lld%lld", &a, &b);
a -= start_index;
b -= start_index;
g[a].emplace_back(b);
if(!directed) g[b].emplace_back(a);
}
}
template<ll start_index = 1> void input_tree(ll n){ input_graph<start_index>(n - 1); }
};
template<class Graph> vector<ll> Dijkstra(const Graph& g, ll start){
vector<ll> cost(g.size(), LINF);
vector<bool> used(g.size());
pq<pll> q;
cost[start] = 0;
q.emplace(0, start);
while(q.size()){
ll at = q.top().second;
q.pop();
if(used[at]) continue;
used[at] = 1;
each(i, g[at]) if(chmin(cost[i], cost[at] + i.cost)) q.emplace(cost[i], i);
}
return cost;
}
vector<ll> BFS(const UnWeightedGraph& g, ll start){
vector<ll> cost(g.size(), LINF);
queue<ll> q;
cost[start] = 0;
q.push(start);
while(q.size()){
ll at = q.front();
q.pop();
each(i, g[at]) if(chmin(cost[i], cost[at] + i.cost)) q.push(i);
}
return cost;
}
template<class Graph> vector<vector<ll>> WarshallFloyd(const Graph& g){
ll n = g.size();
vector<vector<ll>> cost(n, vector<ll>(n, LINF));
queue<ll> q;
for(ll i = 0; i < n; i++) cost[i][i] = 0;
for(ll i = 0; i < n; i++) for(auto& j : g[i]) cost[i][j] = j.cost;
for(ll k = 0; k < n; k++) for(ll i = 0; i < n; i++) for(ll j = 0; j < n; j++) chmin(cost[i][j], cost[i][k] + cost[k][j]);
return cost;
}