Submission #495291

#TimeUsernameProblemLanguageResultExecution timeMemory
495291ZielEvacuation plan (IZhO18_plan)C++17
0 / 100
526 ms199084 KiB
/**
 * LES GREATEABLES BRO TEAM
**/

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
#define sz(x) (int)x.size()
const bool FLAG = false;
void setIO(const string &f = "");

string to_string(const string s) {
	return '"' + s + '"';
}
string to_string(const char c) {
 	return char(39) + string(1, c) + char(39);
}
string to_string(const char* s) {
 	return to_string(string(s));
}
string to_string(bool f) {
	return (f ? "true" : "false");
}
template<class A, class B>
string to_string(const pair<A, B> x) {
	return "(" + to_string(x.first) + ", " + to_string(x.second) + ")";
}
template<class A, class B, class C>
string to_string(const tuple<A, B, C> x) {
	return "(" + to_string(get<0>(x)) + ", " + to_string(get<1>(x)) + ", " + to_string(get<2>(x)) + ")";
}
template<class A, class B, class C, class D>
string to_string(const tuple<A, B, C, D> x) {
	return "(" + to_string(get<0>(x)) + ", " + to_string(get<1>(x)) + ", " + to_string(get<2>(x)) + ", " + to_string(get<3>(x)) + ")";
}
template<class T>
string to_string(const T v) {
	string res = "{"; bool f = true;
	for (auto x: v)
		res += (f ? to_string(x) : ", " + to_string(x)), f = false;
	return res + "}";
}
void debug_args() { cerr << "]\n"; }
template<class H, class... T>
void debug_args(H x, T... y) {
	cerr << to_string(x);
	if (sizeof... (y))
	cerr << ", ";
	debug_args(y...);
}

#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]: [", debug_args(__VA_ARGS__);
#else
#define debug(...) 47
#endif

#define int ll

const int N = 1e6 + 13, L = 18, INF = 1e10 + 15;

struct Edge {
	int x, y, w1, w2;
};

bool visited[N];
ll up[L][N], mx[L][N], comp[N], par[N], siz[N], level[N], d[N];
vector<vector<int>> adj2(N);

int find_set(int x) {
	if (x == par[x])
		return x;
	return par[x] = find_set(par[x]);
}
void union_sets(int a, int b) {
	a = find_set(a);
	b = find_set(b);
	if (a != b) {
		if (siz[a] < siz[b])
			swap(a, b);
		siz[a] += siz[b];
		par[b] = a;
	}
}

void dfs(int c, int v, int pr, int w) {
	visited[v] = 1;
	comp[v] = c;
	up[0][v] = pr;
	mx[0][v] = w;
	level[v] = level[pr] + 1;
	for (int i = 1; i < 18; i++) {
		up[i][v] = up[i - 1][up[i - 1][v]];
		mx[i][v] = min(mx[i - 1][v], mx[i - 1][mx[i - 1][v]]);
	}
	for (auto to: adj2[v]) {
		if (to != pr)
			dfs(c, to, v, min(w, d[to]));
	}
}
int lca(int a, int b) {
	if (level[a] > level[b])
		swap(a, b);
	int res = 1e9 + 23;
	for (int i = 17; i >= 0; i--) {
		if (level[a] <= level[up[i][b]]) {
			res = min(res, mx[i][b]);
			b = up[i][b];
		}
	}
	for (int i = 17; i >= 0; i--) {
		if (up[i][a] != up[i][b]) {
			res = min(res, min(mx[i][a], mx[i][b]));
			a = up[i][a];
			b = up[i][b];
		}
	}
	res = min(res, min(mx[0][a], mx[0][b]));
	return res;
}

signed main() {
    setIO();
    
    int n, m;
    cin >> n >> m;
    vector<vector<pair<int, int>>> adj(n + 1);
    set<pair<int, int>> edges;
    for (int i = 0, x, y, z; i < m; i++) {
    	cin >> x >> y >> z;
    	adj[x].push_back({y, z});
    	adj[y].push_back({x, z});
    	edges.insert({min(x, y), max(x, y)});
    }
    for (int i = 0; i <= 22; i++)
    	for (int j = 0; j <= n + n; j++)
    		mx[i][j] = INF, d[j] = INF;

    int k;
    cin >> k;
    vector<int> g(k + 1);
    set<int> npp;
    for (int i = 1; i <= k; i++) {
    	cin >> g[i];
    	npp.insert(g[i]);
    }

    {
    	set<pair<int, int>> q;
    	for (int i = 1; i <= k; i++) {
    		q.insert({0, g[i]});
    		d[g[i]] = 0;
    	}
		while (sz(q)) {
			int v = q.begin()->second;
			q.erase(q.begin());

			for (auto [to, len]: adj[v]) {
				if (d[to] > d[v] + len) {
					q.erase({d[to], to});
					d[to] = d[v] + len;
					q.insert({d[to], to});
				}
			}
		}
    }

    vector<Edge> mst;
    for (auto [x, y]: edges) {
    	if (!npp.count(x) && !npp.count(y)) {
    		Edge cur;
    		cur.x = x, cur.y = y;
    		cur.w1 = min(d[x], d[y]), cur.w2 = max(d[x], d[y]);
    		mst.push_back(cur);
    	}
    }
    bool flag12 = true;
    if (sz(mst)) {
	    sort(mst.begin(), mst.end(), [](Edge x, Edge y) {
    		if (x.w1 == y.w1)
    			return x.w2 > y.w2;
	    	return x.w1 > y.w1;
    	});
	    for (int i = 1; i <= n; i++)
    		par[i] = i, siz[i] = 1;
	    for (auto x: mst) {
    		if (find_set(x.x) != find_set(x.y)) {
    			union_sets(x.x, x.y);
    			adj2[x.x].push_back(x.y);
	    		adj2[x.y].push_back(x.x);
    		}
	    }
    	int comp_id = 1;
	    for (int i = 1; i <= n; i++) {
    		if (!visited[i]) {
    			dfs(comp_id, i, 0, d[i]);
    			comp_id++;
	    	}
    	}
    } else
    	flag12 = false;

    int qr;
    cin >> qr;

    while (qr--) {
    	int s, t;
    	cin >> s >> t;
    	if (!flag12) {
    		cout << "0\n";
    		continue;
    	}
    	if (edges.count({min(s, t), max(s, t)})) {
    		cout << min(d[s], d[t]) << '\n';
    	} else if ((npp.count(s) || npp.count(t)) || (comp[s] != comp[t])) {
    		cout << "0\n";
    	} else {
    		cout << lca(s, t) << '\n';
    	}
    }

    
    return 0;
}

void setIO(const string &f) {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    if (fopen((f + ".in").c_str(), "r")) {
        freopen((f + ".in").c_str(), "r", stdin);
        freopen((f + ".out").c_str(), "w", stdout);
    }
}

Compilation message (stderr)

plan.cpp: In function 'void setIO(const string&)':
plan.cpp:232:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  232 |         freopen((f + ".in").c_str(), "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
plan.cpp:233:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  233 |         freopen((f + ".out").c_str(), "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...