이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#define int ll
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, bool> plb;
typedef pair<ll, int> pli;
const int MAXN = 2000;
const int MAXM = 12000;
const int MAX_PATH = 1e5;
const ll inf = 1e15;
class path {
public:
ll len;
int s, e;
path(ll l, int s, int e) : len(l), s(s), e(e) {}
path() {}
};
vector<int> edges[MAXN];
pii init_edge[2*MAXN]; // dest, weight
vector<int> dual[MAXM];
int ecount = 0;
int make_edge() {
return (ecount++);
}
path dist[MAXN][MAXN][5]; // 0 : normal, 1 : first diff, 2 : f/e, 3 : e, 4 : e/f
ll edge_dist[2*MAXN][2*MAXN];
bool vis[MAXM]; // bitset?
int seq[MAX_PATH];
int n, m, t, l;
path min(path a, path b) {
if (a.len <= b.len) return a;
return b;
}
path comb(path a, path b) {
assert(a.e != b.s);
if (a.len == inf || b.len == inf) return path(inf, -1, -10);
return path(a.len+b.len, a.s, b.e);
}
class stree {
public:
int lp, rp;
stree *l = nullptr;
stree *r = nullptr;
path seg[5];
stree(int lv, int rv) {
lp = lv;
rp = rv;
if (lp < rp) {
int mid = (lp+rp)/2;
l = new stree(lp, mid);
r = new stree(mid+1, rp);
}
make();
}
int rdiff(int a) {
if (a == 0) return 3;
return 2;
}
void avoid(path seg[], int s, int e, int &a) { // best path avoiding these things
if (seg[a].s == s) a = 1;
if (seg[a].e == e) a = rdiff(a);
if (seg[a].s == s) a++;
}
void make() { // really slow. Could probably be faster
if (lp == rp) {
for (int i = 0; i < 5; i++) seg[i] = dist[seq[lp]][seq[lp+1]][i];
return;
}
for (int i = 0; i < 5; i++) {
int a = 0, b = 0;
int lv = -2, rv = -2;
if (i == 1 || i == 2) lv = seg[0].s;
if (i == 4) lv = seg[3].s;
if (i == 2) rv = seg[1].e;
if (i == 3 || i == 4) rv = seg[0].e;
avoid(l->seg, lv, -2, a);
avoid(r->seg, l->seg[a].e, rv, b);
seg[i] = comb(l->seg[a], r->seg[b]);
a = 0, b = 0;
avoid(r->seg, -2, rv, b);
avoid(l->seg, lv, r->seg[b].s, a);
seg[i] = min(seg[i], comb(l->seg[a], r->seg[b]));
}
}
void upd(int p) {
if (lp > p || rp < p) return;
if (lp == rp) return make();
l->upd(p);
r->upd(p);
make();
}
};
stree *tree;
void dijkstra(int s) {
fill(edge_dist[s], edge_dist[s]+2*m, inf);
fill(vis, vis+MAXM, 0); // could optimize by expanding dists to make pq smaller
priority_queue<pli, vector<pli>, greater<pli>> pq;
pq.push(pli(init_edge[s].second, s));
while (!pq.empty()) {
pli tp = pq.top();
pq.pop();
if (vis[tp.second]) continue;
if (tp.second < 2*m) edge_dist[s][tp.second] = tp.first;
vis[tp.second] = 1;
for (int nxt: dual[tp.second]) {
if (vis[nxt]) continue;
ll ndist = tp.first+((nxt<2*m) ? init_edge[nxt].second : 0);
pq.push(pli(ndist, nxt));
}
}
}
signed main() {
ios_base::sync_with_stdio(false); cin.tie(NULL);
cin >> n >> m >> t >> l;
for (int i = 0; i < m; i++) {
int a, b, c;
cin >> a >> b >> c; a--; b--;
init_edge[2*i] = pii(b, c);
init_edge[2*i+1] = pii(a, c);
edges[a].push_back(make_edge());
edges[b].push_back(make_edge());
}
for (int i = 0; i < n; i++) {
vector<int> pref;
vector<int> suf;
for (int j = 0; j < edges[i].size(); j++) {
pref.push_back(make_edge());
dual[pref.back()].push_back(edges[i][j]);
}
for (int j = 0; j < edges[i].size(); j++) {
suf.push_back(make_edge());
dual[suf.back()].push_back(edges[i][j]);
}
for (int j = 1; j < edges[i].size(); j++) {
dual[pref[j]].push_back(pref[j-1]);
dual[suf[j-1]].push_back(suf[j]);
}
for (int j = 0; j < edges[i].size(); j++) {
if (j)dual[edges[i][j]^1].push_back(pref[j-1]);
if (j<edges[i].size()-1)dual[edges[i][j]^1].push_back(suf[j+1]);
}
}
for (int i = 0; i < 2*m; i++) dijkstra(i); // much cleaner?
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
dist[i][j][0] = path(inf, -1, -10);
for (int a: edges[i]) {
for (int b: edges[j]) {
dist[i][j][0] = min(dist[i][j][0], path(edge_dist[a][b^1], a, b));
}
}
// 1
dist[i][j][1] = path(inf, -1, -10);
for (int a: edges[i]) {
if (a == dist[i][j][0].s) continue;
for (int b: edges[j]) {
dist[i][j][1] = min(dist[i][j][1], path(edge_dist[a][b^1], a, b));
}
}
// 2
dist[i][j][2] = path(inf, -1, -10);
for (int a: edges[i]) {
if (a == dist[i][j][0].s) continue;
for (int b: edges[j]) {
if (b == dist[i][j][1].e) continue;
dist[i][j][2] = min(dist[i][j][2], path(edge_dist[a][b^1], a, b));
}
}
// 3
dist[i][j][3] = path(inf, -1, -10);
for (int a: edges[i]) {
for (int b: edges[j]) {
if (b == dist[i][j][0].e) continue;
dist[i][j][3] = min(dist[i][j][3], path(edge_dist[a][b^1], a, b));
}
}
// 4
dist[i][j][4] = path(inf, -1, -10);
for (int a: edges[i]) {
if (a == dist[i][j][3].s) continue;
for (int b: edges[j]) {
if (b == dist[i][j][0].e) continue;
dist[i][j][4] = min(dist[i][j][4], path(edge_dist[a][b^1], a, b));
}
}
}
}
for (int i = 0; i < l; i++) {
cin >> seq[i];
seq[i]--;
}
tree = new stree(0, l-2);
for (int i = 0; i < t; i++) {
int x, v; cin >> x >> v;
x--; v--;
seq[x] = v;
if (x) tree->upd(x-1);
if (x < l-1) tree->upd(x);
if (tree->seg[0].len == inf) cout << "-1\n";
else cout << tree->seg[0].len << "\n";
}
return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
wild_boar.cpp: In function 'int main()':
wild_boar.cpp:140:21: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
140 | for (int j = 0; j < edges[i].size(); j++) {
| ~~^~~~~~~~~~~~~~~~~
wild_boar.cpp:144:21: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
144 | for (int j = 0; j < edges[i].size(); j++) {
| ~~^~~~~~~~~~~~~~~~~
wild_boar.cpp:148:21: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
148 | for (int j = 1; j < edges[i].size(); j++) {
| ~~^~~~~~~~~~~~~~~~~
wild_boar.cpp:152:21: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
152 | for (int j = 0; j < edges[i].size(); j++) {
| ~~^~~~~~~~~~~~~~~~~
wild_boar.cpp:154:9: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
154 | if (j<edges[i].size()-1)dual[edges[i][j]^1].push_back(suf[j+1]);
| ~^~~~~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |