「JOISC 2018 Day 4」野猪

感觉这种思路挺有用且常用?

虽然有限制,但是限制并不是很大。

单独考虑两个点之间的位置,当两边的路线对其造成干扰的时候,这种干扰并不会很大,我们可以求出所有可能的答案,于是只有四种。对于计算答案直接线段树维护dp就行了。

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll inf = 0x3f3f3f3f3f3f3f3f;
const int maxn = 2010;
const int maxL = 1e5 + 10;
class Dire {
public:
	int v, w, id;
	Dire(int v = 0, int w = 0, int id = 0) : v(v), w(w), id(id) {
	}
};
class Edge {
public:
	int u, v, w;
	Edge(int u = 0, int v = 0, int w = 0) : u(u), v(v), w(w) {
	}
};
vector<Dire> G[maxn], R[maxn];
Edge E[maxn << 1];
ll dis[maxn << 1][maxn << 1];
bool vis[maxn << 1];
Dire fin[maxn << 1];
int ecnt;
void Dij(int id) {
	priority_queue<pair<ll, int> > q;
	memset(vis, 0, sizeof(vis));
	memset(fin, 0, sizeof(fin));
	dis[id][id] = E[id].w;
	q.emplace(-dis[id][id], id);
	while(!q.empty()) {
		int cur = q.top().second; q.pop();
		if(vis[cur]) continue;
		vis[cur] = true;
		int u = E[cur].v;
		if(!fin[u].v) for(auto e : G[u]) {
			if(e.v == E[cur].u) {
				fin[u] = e;
				continue;
			}
			if(dis[id][e.id] > dis[id][cur] + e.w) {
				dis[id][e.id] = dis[id][cur] + e.w;
				q.emplace(-dis[id][e.id], e.id);
			}
		}
		else {
			auto e = fin[u];
			if(dis[id][e.id] > dis[id][cur] + e.w) {
				dis[id][e.id] = dis[id][cur] + e.w;
				q.emplace(-dis[id][e.id], e.id);
			}
		}
	}
}
class Path {
public:
	int s, t;
	ll w;
	Path(int s = 0, int t = 0, ll w = 0) : s(s), t(t), w(w) {
	}
};
Path GetPath(int u, int v, int s, int t) {
	Path res(0, 0, inf);
	for(auto es : G[u]) {
		if(es.v == s) continue;
		for(auto et : R[v]) {
			if(et.v == t) continue;
			if(dis[es.id][et.id] < res.w) {
				res = Path(es.v, et.v, dis[es.id][et.id]);
			}
		}
	}
	return res;
}

class Matrix {
public:
	ll d[4][4];
	ll* operator [](int n) {
		return d[n];
	}
	const ll* operator [](int n) const {
		return d[n];
	}
	Matrix() {memset(d, 0x3f, sizeof(d));}
	Matrix operator * (const Matrix& rhs) const {
		Matrix res;
		for(int i = 0; i < 4; i++) {
			for(int j = 0; j < 4; j++) {
				for(int k = 0; k < 4; k++) {
					res[i][j] = min(res[i][j], d[i][k] + rhs[k][j]);
				}
			}
		}
		return res;
	}
};

class SegTree {
public:
	Matrix tr[maxL << 2];
	void __update(int k) {
		tr[k] = tr[k << 1] * tr[k << 1 | 1];
	}
	void modify(int k, int l, int r, int addr, Matrix val) {
		if(l == r) {
			tr[k] = val;
			return;
		}
		int mid = (l + r) >> 1;
		if(addr <= mid) modify(k << 1, l, mid, addr, val);
		else modify(k << 1 | 1, mid + 1, r, addr, val);
		__update(k);
	}
	ll query() {
		ll res = inf;
		for(int i = 0; i < 4; i++) {
			for(int j = 0; j < 4; j++) {
				res = min(res, tr[1][i][j]);
			}
		}
		return res;
	}
}sgt;

Path P[maxn][maxn][4];

Matrix GetMatrix(int u, int v, int w) {
	Matrix res;
	for(int i = 0; i < 4; i++) {// v->w
		for(int j = 0; j < 4; j++) {
			if(P[u][v][j].t != P[v][w][i].s) res[j][i] = P[v][w][i].w;
		}
	}
	
	
//	for(int i = 0; i < 4; i++)  {
//		for(int j = 0; j < 4; j++) {
//			cout << res[i][j] << ' ';
//		}
//		cout << '\n';
//	}
//			cout << '\n';
	return res;
} 

int n, m, q, L;
int a[maxL];
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n >> m >> q >> L;
	for(int i = 1, u, v, w; i <= m; i++) {
		cin >> u >> v >> w;
		ecnt++;
		G[u].emplace_back(v, w, ecnt);
		R[v].emplace_back(u, w, ecnt);
		E[ecnt] = Edge(u, v, w);
		ecnt++;
		G[v].emplace_back(u, w, ecnt);
		R[u].emplace_back(v, w, ecnt);
		E[ecnt] = Edge(v, u, w);
	}
	for(int i = 1; i <= L; i++) cin >> a[i];
	memset(dis, 0x3f, sizeof(dis));
	for(int i = 1; i <= ecnt; i++) {
		Dij(i);
	}
//	for(int i = 1; i <= ecnt; i++) {
//		for(int j = 1; j <= ecnt; j++) {
//			cout << E[i].u << ' ' << E[i].v << ' ' << E[j].u << ' ' << E[j].v << ':' << dis[i][j] << '\n';
//		}
//	}
	for(int u = 1; u <= n; u++) {
		for(int v = 1; v <= n; v++) {
			if(u == v) continue;
			P[u][v][0] = GetPath(u, v, 0, 0);
			P[u][v][1] = GetPath(u, v, P[u][v][0].s, P[u][v][0].t);
			P[u][v][2] = GetPath(u, v, P[u][v][1].s, P[u][v][0].t);
			P[u][v][3] = GetPath(u, v, P[u][v][0].s, P[u][v][1].t);
		}
	}
	Matrix tmp;
	for(int i = 0; i < 4; i++)  {
		for(int j = 0; j < 4; j++) {
			tmp[i][j] = P[a[1]][a[2]][j].w;
//			cout << tmp[i][j] << ' ';
		}
//		cout << '\n';
	}
//			cout << '\n';
	sgt.modify(1, 1, L - 1, 1, tmp);
	for(int i = 2; i < L; i++) {
		sgt.modify(1, 1, L - 1, i, GetMatrix(a[i - 1], a[i], a[i + 1]));
	}
//	cout << sgt.query() << '\n';
	while(q--) {
		int x, y;
		cin >> x >> y;
		a[x] = y;
		for(int i = x - 1; i <= x + 1 && i < L; i++) 
			sgt.modify(1, 1, L - 1, i, GetMatrix(a[i - 1], a[i], a[i + 1]));
		ll res = sgt.query();
		cout << (res < inf ? res : -1) << '\n';
	}
} 
/*
4 4 0 3
1 2 1
2 3 1
1 3 1
1 4 1
4
1
4

*/
posted @ 2024-02-17 19:57  N2MENT  阅读(17)  评论(0)    收藏  举报