zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    自定义 ClassLoader
    HashCode 解析
    Unsafe与CAS
    ReentrantLock实现原理深入探究
    javaNIO:选择器--实践 Selector
    javaNIO:选择器--理论 Selector
    javaNIO:Socket通道
    CentOs 7 kong 2.3.X oss 自定义插件
    CentOs 7 kong 2.3.X oss 部署安装
    CentOS7 yum安装、配置PostgreSQL 9.6
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10549208.html
Copyright © 2011-2022 走看看