Submission #781244

#TimeUsernameProblemLanguageResultExecution timeMemory
781244Programmer123Islands (IOI08_islands)C++17
70 / 100
343 ms131072 KiB
#pragma GCC optimize("O3") #include <bits/stdc++.h> #define int long long int signed dest[1000000]; signed length[1000000]; std::vector<signed> backEdges[1000000]; std::bitset<1000000> seen; int bestPath[1000000]; #ifdef LOCAL #define debug std::cout #else #define debug std::stringstream() #endif void findComponent(signed node, std::vector<signed> &data) { if (seen[node]) return; data.push_back(node); seen[node] = true; findComponent(dest[node], data); for (auto x: backEdges[node]) { findComponent(x, data); } } int treeSum(int node) { int sum = 0; for (auto x: backEdges[node]) { if (!seen[x]) { sum += length[x] + treeSum(x); } } return sum; } int bestSingle(int node) { if (bestPath[node] != 0) { return bestPath[node]; } int best = 0; for (auto x: backEdges[node]) { if (!seen[x]) { best = std::max(best, length[x] + bestSingle(x)); } } return bestPath[node] = best; } int bestDouble(int node) { int best = 0; int secondBest = 0; std::vector<int> back; for (auto x: backEdges[node]) { if (!seen[x]) { int score = length[x] + bestSingle(x); if (score > best) { secondBest = best; best = score; } else if (score > secondBest) { secondBest = score; } } } return best + secondBest; } //Best score, assuming doesn't pass through edge between start and end of cycle. int bestA(std::vector<signed> &cycle) { int best = 0; int current = 0; int bestBehind = 0; for (int i = 0; i < cycle.size(); ++i) { best = std::max(best, bestSingle(cycle[i]) + current + bestBehind); bestBehind = std::max(bestBehind, bestSingle(cycle[i]) - current); current += length[cycle[i]]; } return best; } //Best score, assuming passes through edge between start and end of cycle int bestB(std::vector<signed> &cycle) { int current = 0; // std::vector<int> lengthForward; // for (int i = 0; i < cycle.size() - 1; ++i) { // lengthForward.push_back(current); // current += length[cycle[i]]; // } current = 0; std::vector<int> lengthBackward; for (int i = 0; i < cycle.size() - 1; ++i) { lengthBackward.push_back(current); current += length[cycle[cycle.size() - 2 - i]]; } for (int i = 0; i < cycle.size() - 1; ++i) { //lengthForward[i] += bestSingle(cycle[i]); lengthBackward[i] += bestSingle(cycle[cycle.size() - 1 - i]); } for (int i = 1; i < cycle.size() - 1; ++i) { //lengthForward[i] = std::max(lengthForward[i], lengthForward[i - 1]); lengthBackward[i] = std::max(lengthBackward[i], lengthBackward[i - 1]); } int best = 0; int lengthForward = length[cycle[cycle.size() - 1]]; int bestForward = lengthForward + bestSingle(cycle[0]); for (int i = 0; i < cycle.size() - 1; ++i) { best = std::max(best, bestForward + lengthBackward[cycle.size() - 2 - i]); lengthForward += length[cycle[i]]; bestForward = std::max(bestForward, lengthForward + bestSingle(cycle[i + 1])); } return best; } int componentSum(const std::vector<signed> &component) { for (auto x: component) { seen[x] = false; } int root = component[0]; while (!seen[root]) { seen[root] = true; root = dest[root]; } for (auto x: component) { seen[x] = false; } std::vector<signed> cycle; cycle.push_back(root); seen[root] = true; for (int x = dest[root]; x != root; x = dest[x]) { cycle.push_back(x); seen[x] = true; } int best = 0; for (auto x: component) { best = std::max({best, bestDouble(x), bestSingle(x)}); } best = std::max(best, bestA(cycle)); best = std::max(best, bestB(cycle)); for (auto x: component) { seen[x] = true; } return best; } signed main() { #ifdef LOCAL freopen("INPUT", "r", stdin); #endif std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr); int N; std::cin >> N; //seen = new bool[N]; for (signed i = 0; i < N; ++i) { seen[i] = false; signed x, l; std::cin >> x >> l; x--; dest[i] = x; length[i] = l; backEdges[x].push_back(i); } int total = 0; for (int i = 0; i < N; ++i) { if (!seen[i]) { std::vector<signed> component; findComponent(i, component); total += componentSum(component); } } std::cout << total << std::endl; }

Compilation message (stderr)

islands.cpp: In function 'long long int bestA(std::vector<int>&)':
islands.cpp:72:23: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   72 |     for (int i = 0; i < cycle.size(); ++i) {
      |                     ~~^~~~~~~~~~~~~~
islands.cpp: In function 'long long int bestB(std::vector<int>&)':
islands.cpp:90:23: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   90 |     for (int i = 0; i < cycle.size() - 1; ++i) {
      |                     ~~^~~~~~~~~~~~~~~~~~
islands.cpp:94:23: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   94 |     for (int i = 0; i < cycle.size() - 1; ++i) {
      |                     ~~^~~~~~~~~~~~~~~~~~
islands.cpp:98:23: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   98 |     for (int i = 1; i < cycle.size() - 1; ++i) {
      |                     ~~^~~~~~~~~~~~~~~~~~
islands.cpp:105:23: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  105 |     for (int i = 0; i < cycle.size() - 1; ++i) {
      |                     ~~^~~~~~~~~~~~~~~~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...