建通道

建通道

http://www.nowcoder.com/questionTerminal/1ad2f38ae0444c9ab668c0db4a000ea7

建通道
https://ac.nowcoder.com/acm/contest/3003/I
图片说明

算是考察位运算吧?
lowbit(0)=0,连接代价为0,可进行去重操作,去掉与之权值相等的
如果最后只剩一个 则直接输出 0
x=vi^vj
!=1时,找最小位的二进制k(在该位上,所有权值中 1 与 0 同时并存(因1^0=1),若同时并存,所有通道间可
进行1-0 0-1 全部连通,若仅存在1或仅存在0,就没有通道能够相连)

#pragma warning (disable :4996)
#include <iostream>
#include <cstdio>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 10;

ll W[N];
map<int, int> vis;
int main() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%lld", &W[i]);
        if (vis[W[i]]) {   //权值一样,lowbit()为0,连接代价为0,去重
            i--, n--;
        }
        vis[W[i]] = 1;
    }
    if (n == 1) {
        cout << "0" << endl; //都相同
        return 0;
    }
    ll cost = 0;
    ll ans = 1;
    for (int i = 1;; i++) {
        int t1 = 0, t2 = 0;  //当前位是否存在1 和 0同时并存,若存在则可一次0-1 1-0 全部连通,不存在则该位无法
        for (int j = 1; j <= n; j++) {
            int tmp = W[j] & 1;
            W[j] >>= 1;  //右移一位 /=2
            if (tmp == 1) t1 = 1;
            if (tmp == 0) t2 = 1;
        }
        if (t1 && t2) {
            cost = ans * (n - 1) * 1ll;
            break;
        }
        ans *= 2ll;
    }
    cout << cost << endl;


}
全部评论

相关推荐

A_SOUL_Off...:疑似加班加出幻觉了
点赞 评论 收藏
分享
11-13 14:37
门头沟学院 Java
点赞 评论 收藏
分享
12-19 16:52
门头沟学院
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务