赞
踩



n 个点 m 条边,求最小或 ( or ) 生成树,即树的所有边或值最小。
由于是求最后所有边或的值最小,或值即对于生成树的所有边来说,他们的每个对应位只要有一个 1 那么这位最终就是 1 ,要是想结果尽可能小,那么我们当然是希望每个对应位都是 0 才好,如果无法为 0 ,那么这一位越低越好,因此我们可以从高位往低位枚举每一位,如果这一位全 0 的边能够凑成一棵生成树,那么这一位为 1 的边就可以不要,那么最终结果的这一位就可以为 0 。要是凑不成,那么说明需要有这一位为 1 的边参与才能构成生成树,最终结果的这一位就为 1 。记录枚举的所有位数 0 1 情况,加起来就是答案。
//#pragma GCC optimize(3)//O3 //#pragma GCC optimize(2)//O2 #include<iostream> #include<string> #include<map> #include<set> //#include<unordered_map> #include<queue> #include<cstdio> #include<vector> #include<cstring> #include<stack> #include<algorithm> #include<iomanip> #include<cmath> #include<fstream> #define X first #define Y second #define base 233 #define pb push_back #define INF 0x3f3f3f3f3f3f3f3f #define pii pair<int,int> #define lowbit(x) x & -x #define inf 0x3f3f3f3f //#define int long long //#define double long double //#define rep(i,x,y) for(register int i = x; i <= y;++i) using namespace std; typedef long long ll; typedef unsigned long long ull; const double pai=acos(-1.0); const int maxn=1e6+10; const int mod=1e9+7; const double eps=1e-9; const int N=5e3+10; /*--------------------------------------------*/ inline int read() { int k = 0, f = 1 ; char c = getchar() ; while(!isdigit(c)){if(c == '-') f = -1 ;c = getchar() ;} while(isdigit(c)) k = (k << 1) + (k << 3) + c - 48 ,c = getchar() ; return k * f ; } /*--------------------------------------------*/ int t,n,m,pre[maxn]; bool vis[maxn]; struct node { int x; int y; int w; }p[maxn]; int find(int x) { if(x==pre[x]) return x; else return pre[x]=find(pre[x]); } void unions(int x,int y) { int fx=find(x); int fy=find(y); if(fx!=fy) pre[fx]=fy; } int main() { // ios::sync_with_stdio(false); // cin.tie(0);cout.tie(0); cin>>t; while(t--) { cin>>n>>m; for(int i=1;i<=m;i++) cin>>p[i].x>>p[i].y>>p[i].w; int ans=0; for(int i=31;i>=0;i--) { for(int j=1;j<=n;j++) pre[j]=j; for(int j=1;j<=m;j++) { if(vis[j]) continue; if((p[j].w>>i)&1) continue; unions(p[j].x,p[j].y); } int sum=0; for(int j=1;j<=n;j++) if(pre[j]==j) sum++; if(sum==1) { for(int j=1;j<=m;j++) if((p[j].w>>i)&1) vis[j]=1; } else ans+=(1<<i); } cout<<ans<<endl; for(int i=1;i<=m;i++) vis[i]=0; } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。