Submission #397846

#TimeUsernameProblemLanguageResultExecution timeMemory
397846maomao90Roadside Advertisements (NOI17_roadsideadverts)C++14
70 / 100
1087 ms12116 KiB
#include <cstdio> #include <vector> #include <cstring> #include <utility> #include <algorithm> #include <set> #include <tuple> using namespace std; typedef pair <int, int> ii; typedef tuple <int, int, int> iii; #define INF 1000000005 //#define DEBUG class UnionFind { private: vector <int> p, ranks; public: void initialise(int n) { p.assign(n, 0); ranks.assign(n, 1); for (int i = 0; i < n; i++) p[i] = i; } int findSet(int a) { if (p[a] == a) return a; return p[a] = findSet(p[a]); } bool isSameSet(int a, int b) { return findSet(a) == findSet(b); } void unionSet(int a, int b) { if (!isSameSet(a, b)) { int pa = findSet(a), pb = findSet(b); if (ranks[pa] < ranks[pb]) p[pa] = pb; else { p[pb] = pa; if (ranks[pa] == ranks[pb]) { ranks[pa]++; } } } } }; int V, Q; vector <ii> adjList[50005]; int sponsors[5]; bool isSponsor[50005]; int level[50005]; int dist[50005]; int p[20][50005]; int adjMatrix[50][50]; vector <iii> edgeList; set <int> processing; vector <int> vertices; UnionFind UF; int ans; int LCA(int a, int b) { if (level[a] < level[b]) swap(a, b); for (int i = 19; i >= 0; i--) { if (level[p[i][a]] >= level[b] && p[i][a] != -1) { a = p[i][a]; } } if (a == b) return a; for (int i = 19; i >= 0; i--) { if (p[i][a] != p[i][b]) { a = p[i][a]; b = p[i][b]; } } return p[0][a]; } void root(int source, int prevDist, int prevLvl, int prevP) { dist[source] = prevDist; p[0][source] = prevP; level[source] = prevLvl; for (ii neighbour : adjList[source]) { if (neighbour.first != prevP) { root(neighbour.first, prevDist + neighbour.second, prevLvl + 1, source); } } } int main() { scanf("%d", &V); for (int i = 0; i < V-1; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); adjList[u].emplace_back(v, w); adjList[v].emplace_back(u, w); } memset(p, -1, sizeof(p)); root(0, 0, 0, -1); for (int k = 1; k < 20; k++) { for (int i = 0; i < V; i++) { if (p[k-1][i] != -1) { p[k][i] = p[k-1][p[k-1][i]]; } else p[k][i] = -1; } } #ifdef DEBUG printf("Parent:\n"); for (int i = 0; i < 20; i++) { printf("k=%d:", i); for (int j = 0; j < V; j++) { printf(" %d", p[i][j]); } printf("\n"); } printf("\n"); #endif // DEBUG scanf("%d", &Q); for (int i = 0; i < Q; i++) { memset(isSponsor, false, sizeof(isSponsor)); for (int j = 0; j < 5; j++) { scanf("%d", sponsors + j); isSponsor[sponsors[j]] = true; } edgeList.clear(); processing.clear(); vertices.clear(); // for (int j = 0; j < 30; j++) for (int k = 0; k < 30; k++) { // adjMatrix[j][k] = INF; // } for (int j = 0; j < 5; j++) { int cnt = 0; for (int k = j + 1; k < 5; k++) { int temp = LCA(sponsors[j], sponsors[k]); processing.insert(temp); // adjMatrix[sponsors[j]][temp] = adjMatrix[temp][sponsors[j]] = dist[sponsors[j]] - dist[temp]; // adjMatrix[k][temp] = adjMatrix[temp][k] = dist[k] - dist[temp]; // edgeList.emplace_back(dist[sponsors[j]] - dist[temp], sponsors[j], temp); // edgeList.emplace_back(dist[k] - dist[temp], k, temp); } processing.insert(sponsors[j]); } for (auto &i : processing) vertices.push_back(i); for (int j = 0; j < vertices.size(); j++) { for (int k = j + 1; k < vertices.size(); k++) { int tempj = vertices[j], tempk = vertices[k]; int lca = LCA(tempj, tempk); edgeList.emplace_back(dist[tempj] + dist[tempk] - 2 * dist[lca], tempj, tempk); } } // for (int l = 0; l < 30; l++) for (int j = 0; j < 30; j++) for (int k = 0; k < 30; k++) { // adjMatrix[j][k] = min(adjMatrix[j][k], adjMatrix[j][l] + adjMatrix[l][k]); // } // for (int j = 0; j < 30; j++) for (int k = 0; k < 30; k++) { // if (adjMatrix[j][k] != INF) { // edgeList.emplace_back(adjMatrix[j][k], j, k); // } // } sort(edgeList.begin(), edgeList.end()); ans = 0; UF.initialise(V+5); for (int j = 0; j < edgeList.size(); j++) { int u, v, w; tie(w, u, v) = edgeList[j]; if (!UF.isSameSet(u, v)) { ans += w; UF.unionSet(u, v); } } printf("%d\n", ans); } return 0; } /* 6 4 0 4 0 1 2 1 3 9 3 5 1 3 2 5 2 4 0 3 5 2 0 4 1 3 5 */

Compilation message (stderr)

roadsideadverts.cpp: In function 'int main()':
roadsideadverts.cpp:164:8: warning: unused variable 'cnt' [-Wunused-variable]
  164 |    int cnt = 0;
      |        ^~~
roadsideadverts.cpp:178:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  178 |   for (int j = 0; j < vertices.size(); j++) {
      |                   ~~^~~~~~~~~~~~~~~~~
roadsideadverts.cpp:179:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  179 |    for (int k = j + 1; k < vertices.size(); k++) {
      |                        ~~^~~~~~~~~~~~~~~~~
roadsideadverts.cpp:197:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::tuple<int, int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  197 |   for (int j = 0; j < edgeList.size(); j++)
      |                   ~~^~~~~~~~~~~~~~~~~
roadsideadverts.cpp:109:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  109 |  scanf("%d", &V);
      |  ~~~~~^~~~~~~~~~
roadsideadverts.cpp:113:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  113 |   scanf("%d%d%d", &u, &v, &w);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~~
roadsideadverts.cpp:146:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  146 |  scanf("%d", &Q);
      |  ~~~~~^~~~~~~~~~
roadsideadverts.cpp:152:9: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  152 |    scanf("%d", sponsors + j);
      |    ~~~~~^~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...