Submission #1337223

#TimeUsernameProblemLanguageResultExecution timeMemory
1337223SmuggingSpunDesignated Cities (JOI19_designated_cities)C++20
100 / 100
335 ms35496 KiB
#include<bits/stdc++.h>
#define taskname "A"
using namespace std;
typedef long long ll;
template<class T>void minimize(T& a, T b){
  if(a > b){
    a = b;
  }
}
template<class T>void maximize(T& a, T b){
  if(a < b){
    a = b;
  }
}
const int lim = 2e5 + 5;
const ll INF = 1e18;
int n, q, a[lim], b[lim], c[lim], d[lim], qx[lim];
vector<int>g[lim];
namespace sub1{
  int dis[17][17];
  void dfs(const int root, int s, int p){
    for(int& i : g[s]){
      int d = a[i] ^ b[i] ^ s;
      if(d != p){
        dis[root][d] = dis[root][s] + 1;
        dfs(root, d, s);
      }
    }
  }
  void solve(){
    for(int i = 1; i <= n; i++){
      dfs(i, i, dis[i][i] = 0);
    }
    vector<ll>ans(n + 1, INF);
    for(int mask = 1; mask < (1 << n); mask++){
      vector<vector<bool>>mark(n, vector<bool>(2, false));
      for(int i = 1; i <= n; i++){
        if((mask >> (i - 1)) & 1){
          for(int j = 1; j < n; j++){
            mark[j][dis[i][b[j]] > dis[i][a[j]]] = true;
          }
        }
      }
      ll sum = 0;
      for(int i = 1; i < n; i++){
        if(!mark[i][0]){
          sum += c[i];
        }
        if(!mark[i][1]){
          sum += d[i];
        }
      }
      minimize(ans[__builtin_popcount(mask)], sum);
    }
    for(int i = 1; i <= q; i++){
      cout << ans[qx[i]] << "\n";
    }
  }
}
namespace sub2{
  vector<ll>delta_dc;
  void dfs(int u, int p){
    for(int& i : g[u]){
      int v = a[i] ^ b[i] ^ u;
      if(v != p){
        if(a[i] != u){
          swap(a[i], b[i]);
          swap(c[i], d[i]);
        }
        delta_dc[v] = delta_dc[u] + d[i] - c[i];
        dfs(v, u);
      }
    }
  }
  void solve(){
    delta_dc.resize(n + 1);
    dfs(1, delta_dc[1] = 0);
    ll ans = INF, sum_c = accumulate(c + 1, c + n, 0LL);
    for(int i = 1; i <= n; i++){
      minimize(ans, sum_c + delta_dc[i]);
    }
    cout << ans;
  }
}
namespace sub3{
  vector<ll>delta_dc, dp_one;
  ll ans = INF;
  void dfs(int u, int p){
    minimize(ans, delta_dc[u]);
    ll pf_max = 0;
    for(int& i : g[u]){
      int v = a[i] ^ b[i] ^ u;
      if(v != p){
        if(a[i] != u){
          swap(a[i], b[i]);
          swap(c[i], d[i]);
        }
        delta_dc[v] = delta_dc[u] + d[i] - c[i];
        dfs(v, u);
        maximize(dp_one[u], dp_one[v] + c[i]);
        minimize(ans, -dp_one[v] - c[i] - pf_max + delta_dc[u]);
        maximize(pf_max, dp_one[v] + c[i]);
      }
    }
  }
  void solve(){
    delta_dc.resize(n + 1);
    dp_one.assign(n + 1, 0);
    dfs(1, delta_dc[1] = 0);
    cout << ans + accumulate(c + 1, c + n, 0LL);
  }
}
namespace sub4{
  const int lim = 2e3 + 5;
  int siz[lim];
  ll ans[lim], delta_dc[lim];
  pair<vector<ll>, vector<ll>>dfs(int u, int p){
    vector<ll>f0(2), f1(2);
    f0[f0[siz[u] = 1] = f1[1] = 0] = f1[0] = -INF;
    for(int& i : g[u]){
      int v = a[i] ^ b[i] ^ u;
      if(v != p){
        if(a[i] != u){
          swap(a[i], b[i]);
          swap(c[i], d[i]);
        }
        delta_dc[v] = delta_dc[u] + d[i] - c[i];
        auto [cf0, cf1] = dfs(v, u);
        siz[u] += siz[v];
        vector<ll>nf0(siz[u] + 1, -INF), nf1(siz[u] + 1, -INF);
        for(int x = siz[v]; x > -1; x--){
          maximize(nf0[x], max(cf0[x], cf1[x]) + c[i]);
        }
        for(int x = siz[u] - siz[v]; x > -1; x--){
          maximize(nf0[x], f0[x]);
          maximize(nf1[x], f1[x]);
          for(int y = siz[v]; y > 0; y--){
            maximize(nf1[x + y], max(f0[x], f1[x]) + max(cf0[y], cf1[y]) + c[i]);
          }
        }
        swap(f0, nf0);
        swap(f1, nf1);
      }
    }
    for(int i = 1; i <= siz[u]; i++){
      minimize(ans[i], delta_dc[u] - f1[i]);
    }
    return make_pair(f0, f1);
  }
  void solve(){
    memset(ans, 0x0f, sizeof(ans));
    dfs(1, delta_dc[1] = 0);
    ll sum_c = accumulate(c + 1, c + n, 0LL);
    for(int i = 1; i <= q; i++){
      cout << ans[qx[i]] + sum_c << "\n";
    }
  }
}
namespace sub56{
  ll delta_dc[lim], ans[lim];
  int deg[lim];
  bitset<lim>vis;
  void dfs(int u, int p){
    for(int& i : g[u]){
      int v = a[i] ^ b[i] ^ u;
      if(v != p){
        if(a[i] != u){
          swap(a[i], b[i]);
          swap(c[i], d[i]);
        }
        delta_dc[v] = delta_dc[u] + d[i] - c[i]; 
        dfs(v, u);
      }
    }
  }
  void solve(){
    dfs(1, delta_dc[1] = 0);
    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>>pq;
    for(int i = 1; i <= n; i++){
      if((deg[i] = g[i].size()) == 1){
        pq.push(make_pair(a[g[i][0]] == i ? d[g[i][0]] : c[g[i][0]], i));
      }
    }
    memset(ans, 0, sizeof(ans));
    vis.reset();
    while(pq.size() > 2){
      auto [w, u] = pq.top();
      pq.pop();
      vis[u] = true;
      for(int& i : g[u]){
        int v = a[i] ^ b[i] ^ u;
        if(!vis[v]){
          u = v;
          break;
        }
      }
      if(--deg[u] == 1){
        for(int& i : g[u]){
          int v = a[i] ^ b[i] ^ u;
          if(!vis[v]){
            pq.push(make_pair(w + (a[i] == v ? c[i] : d[i]), u));
            break;
          }
        }
      }
      else{
        ans[pq.size()] = ans[pq.size() + 1] + w;
      }
    }
    ans[1] = accumulate(c + 1, c + n, 0LL) + *min_element(delta_dc + 1, delta_dc + n + 1);
    for(int i = 1; i <= q; i++){
      cout << ans[qx[i]] << "\n";
    }
  }
}
int main(){
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	if(fopen(taskname".inp", "r")){
		freopen(taskname".inp", "r", stdin);
	}
  cin >> n;
  for(int i = 1; i < n; i++){
    cin >> a[i] >> b[i] >> c[i] >> d[i];
    g[a[i]].push_back(i);
    g[b[i]].push_back(i);
  }
  cin >> q;
  for(int i = 1; i <= q; i++){
    cin >> qx[i];
  }
  if(n <= 16){
    sub1::solve();
  }
  else if(q == 1 && qx[1] == 1){
    sub2::solve();
  } 
  else if(q == 1 && qx[1] == 2){
    sub3::solve();
  }
  else if(n <= 2000){
    sub4::solve();
  }
  else{
    sub56::solve();
  }
}

Compilation message (stderr)

designated_cities.cpp: In function 'int main()':
designated_cities.cpp:219:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  219 |                 freopen(taskname".inp", "r", stdin);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...