根据输入考虑建图,x、y两个下标的边权为z,建无向图
这样我们可以得到一些连通块。根据异或和的性质,对于每一个连通块,我们只要知道其中一个点的点权就能推出所有的点权。
最小值考虑贪心,针对当前连通图所有点权二进制数的每一位,假如这一位是1,要想保留更多的1就让别的本位为1的数的这一位是0,于是统计每一位1的个数,若1比0多则起点这一位为1,这样保证了0多。
判定可行性:深搜跑一边,如果遍历过了但是点权不符合多个边的要求,那麽就是无解
int head[N], IDX = 0;struct NODE{int t, ne;ll w=0;}ed[N];
void add(int s,int t,ll w){ed[++IDX].ne = head[s]; ed[IDX].t = t; head[s] = IDX;ed[IDX].w = w;
}
ll n,m;
ll x,y,z,tmp;
bool vis[N];
int val[N],bit[35],ans[N];
map <PII,bool> hse;
bool f = 1;
void dfs1(int now,int st)
{tmp++;val[now] = st;vis[now] = 1;for(int i=0;i<32;i++){if(st>>i&1){bit[i]++;}}for(int i=head[now];i;i=ed[i].ne){int t = ed[i].t;int w = ed[i].w;if(!vis[t]){dfs1(t,st^w);}else{//cout<<val[t]<<' '<<(st^w)<<endl;if(val[t]!=(st^w)){f=0;return ;}}}
}
void dfs2(int now)
{vis[now] = 1;for(int i=head[now];i;i=ed[i].ne){int t = ed[i].t;if(!vis[t]){ans[t] = (ans[now]^ed[i].w);dfs2(t);}}
}
void solve()
{cin>>n>>m;for(int i=1;i<=m;i++){cin>>x>>y>>z;add(x,y,z);add(y,x,z);}for(int i=1;i<=n;i++){if(!vis[i]){for(int j=0;j<32;j++){bit[j]=0;}tmp=1;dfs1(i,0);//cout<<tmp<<endl;if(f==0){cout<<-1<<endl;return ;}for(int j=0;j<32;j++){if(bit[j]>=tmp-bit[j]){ans[i]|=1<<j;}}}}for(int i=1;i<=n;i++) vis[i]=0;for(int i=1;i<=n;i++){if(!vis[i]){dfs2(i);}}for(int i=1;i<=n;i++){cout<<ans[i]<<' ';}
}