zoukankan      html  css  js  c++  java
  • HDU 5883 F

    给定一个图,要求选一个点作为起点,然后经过每条边一次,然后把访问过的点异或起来(访问一次就异或一次),然后求最大值。

    首先为什么会有最大值这样的分类?就是因为你开始点选择不同,欧拉回路的结果不同,因为是回路,所以你的开始点就会被访问多一次,所以如果是欧拉回路的话,还需要O(n)扫一次,枚举每个点作为起点。

    欧拉通路的话,结果是固定的,因为只能从奇数度小的那个点作为起点,奇数度大的那个点作为终点。

    关于点的访问次数:anstime  = Degree[i] / 2; //如果是奇数的,还要加上一。

    因为每两个度就表示:一进一出,度数为2,所以才访问一次。

    奇数度的话,剩下的那一个度就是用来出或则进的,

    然后如果有一个点的度数是0,则可以说明图不联通,

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    const int maxn = 1e5 + 20;
    int a[maxn];
    int Degree[maxn];
    void init(int n) {
        for (int i = 1; i <= n; ++i) {
            Degree[i] = 0;
        }
    }
    void work() {
        int n, m;
        scanf("%d%d", &n, &m);
        init(n);
        for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
        for (int i = 1; i <= m; ++i) {
            int u, v;
            scanf("%d%d", &u, &v);
            Degree[u]++;
            Degree[v]++;
        }
        int root = 0;
        root = 0;
        for (int i = 1; i <= n; ++i) {
            root += Degree[i] & 1;
            if (Degree[i] == 0) {
                printf("Impossible
    ");
                return;
            }
        }
        if (!(root == 0 || root == 2)) {
            printf("Impossible
    ");
            return;
        }
        int ans = 0;
        int tans = 0;
        for (int i = 1; i <= n; ++i) {
            int tim = Degree[i] / 2 + (Degree[i] & 1);
            tim &= 1;
            tans ^= a[i] * tim;
        }
        if (root == 0) {
            for (int i = 1; i <= n; ++i) {
                int gg = tans ^ a[i];
                ans = max(ans, gg);
            }
        } else {
            ans = tans;
        }
        printf("%d
    ", ans);
    }
    
    int main() {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
    //    printf("%d
    ", 1  ^ 3 ^ 4 ^ 5 ^ 6);
        int t;
        scanf("%d", &t);
        while (t--) work();
        return 0;
    }
    View Code
  • 相关阅读:
    [C语言] 交换排序之冒泡排序的特性及实现
    [C语言] 选择排序之鸡尾酒排序的特性及实现
    [C语言] 选择排序之直接选择排序的特性及实现
    计蒜客 蓝桥杯模拟 快速过河
    计蒜客 蓝桥杯模拟 瞬间移动 dp
    计蒜客 蓝桥杯模拟 充话费
    计蒜客 蓝桥杯模拟二 区间合并 打扫教室
    商品类目短文本分类总结
    SpringBoot项目创建及入门基础
    Joyful HDU
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6021106.html
Copyright © 2011-2022 走看看