• Codeforces Round #508 (Div. 2) E. Maximum Matching(欧拉路径)


     E. Maximum Matching

    题目链接:https://codeforces.com/contest/1038/problem/E

    题意:

    给出n个项链,每条项链左边和右边都有一种颜色(范围1~4),然后每条项链都有对应的价值。

    现在你可以任意改变项链的位置,也可以交换左右两边的颜色,问怎么做才能得到最大的价值。一条项链得到价值,就要求其左边的颜色和左边的项链右边颜色相等,并且右边的颜色和右边项链左边的颜色相等。

    题解:

    分析就可以发现这个题就是找一条权值最大的欧拉路径(每条边刚好经过一次),我们这样构造,将两边的颜色看作点,然后价值看作边上的权值并且连接这两个点。

    由于存在欧拉路径的充要条件就是度数为奇数的点不超过两个,这个题目中最多只有四个点,所以我们只需要枚举去掉一条边然后来跑欧拉路径就是了。

    具体细节见代码吧:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 105;
    int n, sum;
    int d[N], vis[N], del[N],check[N];
    struct node {
        int id, v, val;
    };
    vector <node> g[N], edges[N];
    void Euler(int u, int fa) {
        check[u]=1;
        for(auto v : g[u]) {
            if(del[v.id] || vis[v.id])
                continue ;
            vis[v.id]=1;
            sum += v.val;
            Euler(v.v, u);
        }
    }
    bool Can() {
        int cnt = 0;
        for(int i = 1; i <= 4; i++) {
            if(check[i] && (d[i] & 1))
                cnt++;
        }
        return cnt <= 2;
    }
    void init(){
        memset(vis, 0, sizeof(vis));
        memset(check,0,sizeof(check));
        sum = 0;
    }
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> n;
        for(int i = 1; i <= n; i++) {
            int c1, c2, v;
            cin >> c1 >> v >> c2;
            g[c1].push_back(node{i, c2, v});
            g[c2].push_back(node{i, c1, v});
            d[c1]++;
            d[c2]++;
            edges[i].push_back(node{c1, c2, v});
        }
        int ans = 0;
        for(int i = 1; i <= 4; i++) {
            init();
            Euler(i, -1);
            if(Can())
                ans = max(ans, sum);
        }
        for(int i = 1; i <= n; i++) {
            del[i - 1] = 0;
            del[i] = 1;
            d[edges[i][0].id]--;
            d[edges[i][0].v]--;
            for(int j = 1; j <= 4; j++) {
                init();
                Euler(j, -1);
                if(Can()){
                    ans = max(ans, sum);
                }
            }
            d[edges[i][0].id]++;
            d[edges[i][0].v]++;
        }
        cout << ans;
        return 0;
    }
  • 相关阅读:
    app-framework学习--panel传值
    app-framework学习--动态管理panel
    app-framework学习--iscrolldemo
    app-framework学习--中文api
    app-framework学习--iscroll5+jquery+afui上拉加载下拉刷新
    DeepLearning tutorial(5)CNN卷积神经网络应用于人脸识别(详细流程+代码实现)
    提升深度学习模型的表现,你需要这20个技巧
    Deep Learning(深度学习)学习笔记整理系列之常用模型(四、五、六、七)
    池化
    卷积特征提取
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10549208.html
Copyright © 2020-2023  润新知