Codeforces Round #677 (Div. 3)

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;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值