bestcoder #71 1003 找位运算&的最大生成树

Clarke and MST

Accepts: 33

Submissions: 92

Time Limit: 2000/1000 MS (Java/Others)

Memory Limit: 65536/65536 K (Java/Others)

问题描述

克拉克是一名人格分裂患者。某一天克拉克变成了一名图论研究者。
他学习了最小生成树的几个算法,于是突发奇想,想做一个位运算and的最大生成树。
一棵生成树是由n-1n−1条边组成的,且nn个点两两可达。一棵生成树的大小等于所有在生成树上的边的权值经过位运算and后得到的数。
现在他想找出最大的生成树。

输入描述

第一行是一个整数T(1 \le T \le 5)T(1≤T≤5),表示数据组数。
每组数据第一行是两个整数n, m(1 \le n, m \le 300000)n,m(1≤n,m≤300000),分别表示点个数和边个数。其中n, m > 100000n,m>100000的数据最多一组。
接下来mm行,每行33个整数x, y, w(1 \le x, y \le n, 0 \le w \le 10^9)x,y,w(1≤x,y≤n,0≤w≤10?9??),表示x, yx,y之间有一条大小为ww的边。

输出描述

每组数据输出一行一个数,表示答案。若不存在生成树,输出00。

输入样例

1
4 5
1 2 5
1 3 3
1 4 2
2 3 1
3 4 7

输出样例

1这是一道好题,可惜我太笨,比赛的时候没做出来,虽然并不难。。。从大到小枚举位数i,如果能生成树,那么该位的生成树MST(i)一定是前一位+(1<<i),当然对树上所有的边还要满足MST(i)&w==MST(i).

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<set>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

int n,m;
struct Edge
{
    int u,v;
    ll w;
};Edge e[maxn];
int fa[maxn];
int u,v;
ll w;

int find(int x)
{
    return fa[x]==x?x:fa[x]=find(fa[x]);
}

void solve(ll t,ll &ans)
{
    REP(i,1,n) fa[i]=i;
    ans+=t;
    REP(i,1,m){
        u=e[i].u,v=e[i].v,w=e[i].w;
        int x=find(u),y=find(v);
        if(x!=y&&((w&ans)==ans)) fa[x]=y;
    }
    int st=find(1);
    REP(i,2,n){
        if(find(i)!=st){
            ans-=t;return;
        }
    }
}

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
    #endif
    int T;cin>>T;
    while(T--){
        scanf("%d%d",&n,&m);
        REP(i,1,m){
            scanf("%d%d%I64d",&u,&v,&w);
            e[i]=(Edge){u,v,w};
        }
        ll ans=0;
        for(int i=32;i>=0;i--){
            solve(1LL<<i,ans);
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

时间: 2024-12-26 11:28:42

bestcoder #71 1003 找位运算&的最大生成树的相关文章

nyist oj 138 找球号(二)(hash 表+位运算)

找球号(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:5 描述 在某一国度里流行着一种游戏.游戏规则为:现有一堆球中,每个球上都有一个整数编号i(0<=i<=100000000),编号可重复,还有一个空箱子,现在有两种动作:一种是"ADD",表示向空箱子里放m(0<m<=100)个球,另一种是"QUERY",表示说出M(0<M<=100)个随机整数ki(0<=ki<=100000100),分

位运算 找出给定的数中其他数都是两个,有两个是一个的数

题目大意: 给定你n个数, 其中有n-2个数都是两两成对的,有两个是单独出现的,如n = 8, 2 3 2 5 3 6 4 6, 这时候4和5是单独的两个,所以答案就是4,5,其中n的范围是1e6. 思路: 之前做过找一个单独的数的题,那个题是用一个比较巧妙的方法来做的,不过这个也是一类经典问题,用到了强大的位运算,有了那个题的基础再来做这个题就简单了.(附:找一个的题目链接). 刚开始我是用了O(nlogn)的时间复杂度来做的,先排序,然后用类似找一个的方法找出第二个.我觉得对于1e6的数据量

一个序列,除了一个数出现两次,其他数都出现一次,找出来重复的这个数-位运算应用(异或运算)

一个序列,除了一个数出现两次,其他数都出现一次,找出来重复的这个数-位运算应用 面试的题目 贴一下代码: 1 //位运算应用 2 #include<bits/stdc++.h> 3 using namespace std; 4 typedef long long ll; 5 const int maxn=1e5+10; 6 7 int n; 8 int a[maxn]; 9 10 void found(){ 11 int xors=0; 12 for(int i=0;i<n;i++){

NYOJ528 找球号(三)位运算

这个题用位运算就非常简单了,前提是首先熟悉位运算,这里用到一个异或运算,也就是 ^ 这个符号,他的运算规则是:相同为0,不同为1.知道了这个之后,就容易想到相同的两个数异或之后为0,所以下面很关键的一步,也是我想了好久也没想起来的一步,就是把所有的数都异或一遍,那么最后剩下的一定是那个一个的,还有一点需要注意就是任何数和0进行异或运算都还是他本身.下面是代码: 1 #include <iostream> 2 #include <cstdio> 3 4 using namespace

位运算 ZOJ 3870 Team Formation

题目传送门 1 /* 2 题意:找出符合 A^B > max (A, B) 的组数: 3 位运算:异或的性质,1^1=0, 1^0=1, 0^1=1, 0^0=0:与的性质:1^1=1, 1^0=0, 0^1=0, 0^0=0: 4 假设A < B,一定要满足B的最高位对应A的值是0,这样才可能>B(即0^1=1): 5 然后比赛时假设A的极限是类似0111111的情况,最后假设有误: 6 题解是先把每个数最高位(1)的位置统计个数,1<<4 的意思是 000010000:

POJ 1166 The Clocks 位运算与BFS

1.题意:有一组3*3的只有时针的挂钟阵列,每个时钟只有0,3,6,9三种状态:对时针阵列有9种操作,每种操作只对特点的几个时钟拨一次针,即将时针顺时针波动90度,现在试求从初试状态到阵列全部指向0的状态所需要的最小操作数的操作方案: 2.输入输出:输入给出阵列初始状态,0,1,2,3分别表示0,3,6,9:要求输出最快方案的操作序列: 3.分析:IOI 1994的考题,BFS是比较容易想到的方法之一,关键是如何简洁的表示和改变BFS过程中的阵列状态:这里使用位运算的方法:具体如下: 首先一共9

c语言位运算详解

位运算是指按二进制进行的运算.在系统软件中,常常需要处理二进制位的问题.C语言提供了6个位操作运算符.这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型. C语言提供的位运算符列表: 运算符含义描述 & 按位与      如果两个相应的二进制位都为1,则该位的结果值为1,否则为0 | 按位或      两个相应的二进制位中只要有一个为1,该位的结果值为1 ^ 按位异或    若参加运算的两个二进制位值相同则为0,否则为1 ~ 取反        ~

奇妙的位运算

三道leetcode上的题目. Single Number Given an array of integers, every element appears twice except for one. Find that single one. 题意即:一个数组,里面的元素每个都出现了两次,除了一个特殊的,求这个特殊元素.接触过这类题目的coder很快能够脱口而出:直接异或就ok了!因为两个相同的数异或会抵消每个bit位,结果为0. 1 class Solution { 2 public: 3

Codeforces 558C Amr and Chemistry(数论+位运算)

C. Amr and Chemistry time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Amr loves Chemistry, and specially doing experiments. He is preparing for a new interesting experiment. Amr has n differ