Codeforces Round #677 (Div. 3)
阿新 • • 發佈:2020-10-21
Codeforces Round #677 (Div. 3)
F. Zero Remainder Sum
直接dfs列舉所有情況, 然後在加個記憶化
#include<bits/stdc++.h> using namespace std; typedef long long ll; int dp[80][80][70][80]; int mp[100][100], k, n, m; bool judge(int x, int y) { if (x < 1 || y < 1 || x > n || y > m) { return false; } return true; } int dfs(int x, int y, int cnt, int sum) { if (!judge(x, y)) { if (sum == 0) { return 0; } return -1e8; } if (dp[x][y][cnt][sum] != -1) return dp[x][y][cnt][sum]; int ans = -1e8; ans = max(ans, dfs(x, y + 1, cnt, sum)); ans = max(ans, dfs(x + 1, 1, 0, sum)); if (cnt < m / 2) { ans = max(ans, dfs(x, y + 1, cnt + 1, (sum + mp[x][y]) % k ) + mp[x][y]); } if (cnt < m / 2) { ans = max(ans, dfs(x + 1, 1, 0, (sum + mp[x][y]) % k ) + mp[x][y]); } return dp[x][y][cnt][sum] = ans; } int main() { cin >> n >> m >> k; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cin >> mp[i][j]; } } memset(dp, -1, sizeof(dp)); cout << dfs(1, 1, 0, 0) << endl; }
G. Reducing Delivery Cost
先用迪傑斯特拉跑多源最短路, 求出\(dist[i][j]\) i 到j的最短距離, 然後列舉刪的邊\(u, v\) 假設當前要算的是 s到t的最短路, 刪掉u,v時 那麼最短路有可能變成,\(dist[s][u] + dist[v][t]\)或者 \(dist[s][v] + dist[u][t]\)或者是\(dist[s][t]\)取最小就行了
程式碼:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e3 + 7; int dist[N][N], n, m, k, vis[N] ; vector<pair<int, int> > g[N]; struct node { int d, v; bool operator <(const node x) const{ return d > x.d; } }; priority_queue<node>q; void dj (int s) { for (int i = 1; i <= n; i++) { dist[s][i] = 1e8; vis[i] = 0; } dist[s][s] = 0; q.push({0, s}); while (q.size()) { node cd = q.top(); q.pop(); if (vis[cd.v]) continue; vis[cd.v] = 1; for (auto it: g[cd.v]) { int to = it.first; int cost = it.second; if (dist[s][to] > dist[s][cd.v] + cost) { dist[s][to] = dist[s][cd.v] + cost; q.push({dist[s][to], to}); } } } } vector<pair<int, int> >cnt; struct edge{ int u, v, w; }; vector<edge>e; int main() { cin >> n >> m >> k; for (int i = 1; i <= m; i++) { int u, v, w; cin >> u >> v >> w; g[u].push_back({v, w}); g[v].push_back({u, w}); e.push_back({u, v, w}); } for (int i = 1; i <= k; i++) { int u, v; cin >> u >> v; cnt.push_back({u, v}); } for (int i = 1; i <= n; i++) { dj(i); } long long ans = 0; for (int i = 0; i < cnt.size(); i++) { ans += 1ll* dist[cnt[i].first][cnt[i].second]; } long long minn = INT_MAX; for (int i = 0; i < e.size(); i++) { ll cat = ans; int u = e[i].u, v = e[i].v, w = e[i].w; for (int j = 0; j < cnt.size(); j++) { ll res = dist[cnt[j].first][u] + dist[cnt[j].second][v]; ll cn = 0; if (res < dist[cnt[j].first][cnt[j].second]) { cn = dist[cnt[j].first][cnt[j].second] - res; } res = dist[cnt[j].first][v] + dist[cnt[j].second][u]; if (res < dist[cnt[j].first][cnt[j].second]) { cn = max(cn, dist[cnt[j].first][cnt[j].second] - res); } cat = cat - cn; } minn = min(minn, cat); } cout << minn << endl; }