• 2023NOIP A层联测6 万花筒


    题目大意

    有一张有 n n n个点 m m m条边的无向带权图 G G G,小艾将它放到一个万花筒中观察。在万花筒中,对于每条边 ( u , v , w ) ∈ G (u,v,w)\in G (u,v,w)G,会在 H H H中生成全体 ( ( u + 1 )   m o d   + 1 , ( v + i )   m o d   n + 1 , w ) ((u+1)\bmod+1,(v+i)\bmod n+1,w) ((u+1)mod+1,(v+i)modn+1,w)的边,最后的图 H H H就是在万花筒中看到的图。

    求这个图 H H H的最小生成树的权值和,保证生成树存在。

    T T T组数据。

    1 ≤ T ≤ 100 , 1 ≤ n , w ≤ 1 0 9 , ∑ m ≤ 1 0 5 1\leq T\leq 100,1\leq n,w\leq 10^9,\sum m\leq 10^5 1T100,1n,w109,m105


    题解

    对于 G G G中的每一条边 ( u , v , w ) (u,v,w) (u,v,w),令 k = ( u − v + n ) % n k=(u-v+n)\% n k=(uv+n)%n,则在 H H H中,任意两个满足 ( i − j + n ) % n = k (i-j+n)\% n=k (ij+n)%n=k的两个点 i , j i,j i,j都有一条权值为 w w w的边。那么,对于 G G G中的每一条边 ( u , v , w ) (u,v,w) (u,v,w),我们记其对应的 H H H中的边集为 T ( k , w ) T(k,w) T(k,w)

    利用 Kruskal \text{Kruskal} Kruskal算法的思想,我们将这些边集按 w w w从小到大排序,并依次遍历以构建最小生成树。

    设当前的 n n n个点中没有任何两个点有连边,当前枚举到的边集为 T ( k , w ) T(k,w) T(k,w),则将 n n n中所有满足 ( i − j + n ) % n = k (i-j+n)\% n=k (ij+n)%n=k且不在同一个连通块的两个点 i , j i,j i,j连一条边。那么,这 n n n个点就会分为 d = gcd ⁡ ( n , k ) d=\gcd(n,k) d=gcd(n,k)个连通块,且同一个连通块中的点的编号模 d d d后的值一定相等(可以自己举几个例子试一下)。

    这样的话,这个图就连上了 n − d n-d nd条边,边集 T ( k , w ) T(k,w) T(k,w)对答案的贡献为 ( n − d ) × w (n-d)\times w (nd)×w

    再考虑下一组边集 T ( k ′ , w ′ ) T(k',w') T(k,w),类似地,将 n n n中所有满足 ( i − j + n ) % n = k ′ (i-j+n)\% n=k' (ij+n)%n=k且不在同一个连通块的两个点 i , j i,j i,j连一条边。这时,我们发现, i i i所在的连通块中的点模 d d d后的值均为 i % d i\%d i%d j j j所在的连通块中的点模 d d d后的值均为 j % d j\% d j%d,那么我们可以将 i i i j j j连边看作 i % d i\% d i%d j % d j\% d j%d连边( i % d i\% d i%d j % d j\% d j%d的值为 0 0 0时将其值看作 d d d),这样显然是等价的。

    换句话说,我们将每个连通块都看成了一个点,而这个点表示的连通块就是一棵树。

    那么,在连完 T ( k , w ) T(k,w) T(k,w)的边之后,问题可以看作剩下 d d d个点且其中没有任何两个点有连边,要求其在连上剩下的边集后的最小生成树的权值和。

    每次多加一个边集,就按上面所说的操作一次,并算上边的贡献。因为保证生成树存在,所以最终一定只剩下一个点,而这一个点所表示的连通块就是图 H H H的最小生成树。

    将每次操作的贡献求和,即可得到答案。

    时间复杂度为 O ( m ) O(m) O(m)

    code

    #include
    using namespace std;
    int T,n,m,now,d;
    long long ans;
    struct node{
    	int t,w;
    }v[100005];
    bool cmp(node ax,node bx){
    	return ax.w<bx.w;
    }
    int gcd(int i,int j){
    	while(j){
    		i%=j;swap(i,j);
    	}
    	return i;
    }
    int main()
    {
    	freopen("kaleidoscope.in","r",stdin);
    	freopen("kaleidoscope.out","w",stdout);
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d%d",&n,&m);
    		for(int i=1,x,y,z;i<=m;i++){
    			scanf("%d%d%d",&x,&y,&z);
    			v[i].t=(x-y+n)%n;
    			v[i].w=z;
    		}
    		sort(v+1,v+m+1,cmp);
    		now=n;
    		ans=0;
    		for(int i=1;i<=m;i++){
    			d=gcd(now,v[i].t%now);
    			ans+=1ll*(now-d)*v[i].w;
    			now=d;
    		}
    		printf("%lld\n",ans);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
  • 相关阅读:
    【Web】CSS学习笔记
    LeCun指明下一代AI方向:自主机器智能
    I/O设备的I/O控制器
    数据分析技能点-机器学习优化思想
    2022 年恶意软件趋势与安全最佳实践
    linux中的Invalid bound statement (not found) 终极解决办法
    221. 最大正方形
    java计算机毕业设计深州市特色蜜桃产业电子商务系统源程序+mysql+系统+lw文档+远程调试
    k8s----网络通信机制(calico-IPIP,fiannel-VXLAN)caclicoctl命令
    【Unity】渲染性能开挂GPU Animation, 动画渲染合批GPU Instance
  • 原文地址:https://blog.csdn.net/tanjunming2020/article/details/133682689