列表

详情


NC219264. ok起⻜

描述

⻢老师决定起⻜,具体的,他要在饭堂里起⻜。饭堂可以被看成一个  个点  条边的无向联通带权图, 这张图具有一定的性质,我们保证其没有重边和自环,而且,对于任意两个点  来说,最多只会有两条  到  的边不相交的简单路径
⻢老师想在起⻜的过程中顺便种点水稻。对于图上的每一条边 来说,(上面都有一个检查站 和  的检查站是不同的 ),假设这条边的权值为 ,那么⻢老师从  带到  的的水稻种子吨数不能超过 
⻢老师每次起⻜的过程是从  到  ,并且他希望能够将尽可能多的水稻从带  到  ,设这个值为 。由于⻢老师精通影流之主,因此⻢老师可以分成很多分身,不同的分身可以走不同的路径从  到 ,并且每个分身一开始可以带任意多吨水稻种子。由于⻢老师的分身⻓的都一样,所以对于每个检查站  ,⻢老师的所有经过了  的分身带过去的种子吨数不能超过  。 
他想知道对于所有  的值,为了减少输出量,他只需要你求出  其中代表的运算是按位异或。

输入描述

第一行一个正整数 代表数据组数
对于每组数据,第一行两个正整数  , 代表饭堂点数和边数
接下来  行,每行三个正整数  ,代表一条边的端点和边权

输出描述

对于每组数据,输出一行答案。

示例1

输入:

2
3 3 
1 2 5 
2 3 6 
3 1 5 
5 6 
1 2 5 
2 3 6 
3 1 5 
3 4 6 
4 5 5
5 3 6

输出:

27
116

说明:

对于第一组数据,

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 682ms, 内存消耗: 33204K, 提交时间: 2021-04-16 19:16:56

#include<bits/stdc++.h> 
using namespace std;
typedef long long ll;
int p1=5000000;
char buf[5000005];
int gc(){
	if(p1>=5000000)fread(buf,1,5000000,stdin),p1=0;
	return buf[p1++];
}
int rd(){
	int x=0,ch=gc();
	while(!isdigit(ch))ch=gc();
	while(isdigit(ch))x=x*10+ch-'0',ch=gc();
	return x;
}
int n,m,dfn[200005],low[200005],st[200005],fa[200005],loop[200005],top,sign,cnt=0,w[200005];
ll ans=0;
int s[200005][22],size[200005];
vector<int> g[200005];
int gf(int x){
	return fa[x]==x?x:fa[x]=gf(fa[x]);
}
struct E{
	int x,y,val;
}e[200005];
unordered_map<ll,int> mp;
void dfs(int x,int fr){
	dfn[x]=low[x]=++sign,st[++top]=x;
	for(int y:g[x]){
		if(!dfn[y]){
			dfs(y,x),low[x]=min(low[x],low[y]);
			if(low[y]>=dfn[x]){
				loop[0]=0;
				do {
					loop[++loop[0]]=st[top--];
				} while(loop[loop[0]]!=y);
				loop[++loop[0]]=x;
				if(low[y]!=dfn[y]){
					int mn=1e9,mnp=0;
					for(int i=1;i<=loop[0];i++){
						w[i]=mp[200000ll*loop[i]+loop[i%loop[0]+1]];
						if(w[i]<mn)mn=w[i],mnp=i;
					}
					for(int i=1;i<=loop[0];i++)if(i^mnp)e[++cnt]={loop[i],loop[i%loop[0]+1],mn+w[i]};
				}
				else e[++cnt]={x,y,mp[200000ll*x+y]};
			}
		}
		else if(y!=fr)low[x]=min(low[x],dfn[y]);
	}
}
void Solve(){
	n=rd(),m=rd(),cnt=top=sign=ans=0,mp.clear();
	for(int i=1;i<=n;i++)g[i].clear(),dfn[i]=low[i]=0;
	for(int i=1,x,y,z;i<=m;i++)x=rd(),y=rd(),z=rd(),g[x].push_back(y),g[y].push_back(x),mp[200000ll*x+y]=mp[200000ll*y+x]=z;
	dfs(1,0),sort(e+1,e+cnt+1,[](E x,E y){return x.val>y.val;});
	for(int i=1;i<=n;i++){
		fa[i]=i,size[i]=1;
		for(int j=0;j<21;j++)s[i][j]=((i>>j)&1);
	}
	for(int i=1;i<=cnt;i++){
		int x=gf(e[i].x),y=gf(e[i].y),w=e[i].val;
		for(int j=0;j<21;j++){
			if((w>>j)&1)ans+=(1ll<<j)*(1ll*s[x][j]*s[y][j]+1ll*(size[x]-s[x][j])*(size[y]-s[y][j]));
			else ans+=(1ll<<j)*(1ll*s[x][j]*(size[y]-s[y][j])+1ll*s[y][j]*(size[x]-s[x][j]));
		}
		fa[y]=x,size[x]+=size[y];
		for(int j=0;j<21;j++)s[x][j]+=s[y][j];
	}
	cout<<ans<<'\n';
}
int main(){
	int t=rd();
	while(t--)Solve();
}

上一题