码迷,mamicode.com
首页 > 其他好文 > 详细

【AtCoder - 2134】Zigzag MST

时间:2018-03-10 17:50:32      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:for   扩展   connect   one   example   algorithm   ons   infinite   src   

问题描述

We have a graph with N vertices, numbered 0 through N−1. Edges are yet to be added.

We will process Q queries to add edges. In the i-th (1≦iQ) query, three integers Ai,Bi and Ci will be given, and we will add infinitely many edges to the graph as follows:

  • The two vertices numbered Ai and Bi will be connected by an edge with a weight of Ci.
  • The two vertices numbered Bi and Ai+1 will be connected by an edge with a weight of Ci+1.
  • The two vertices numbered Ai+1 and Bi+1 will be connected by an edge with a weight of Ci+2.
  • The two vertices numbered Bi+1 and Ai+2 will be connected by an edge with a weight of Ci+3.
  • The two vertices numbered Ai+2 and Bi+2 will be connected by an edge with a weight of Ci+4.
  • The two vertices numbered Bi+2 and Ai+3 will be connected by an edge with a weight of Ci+5.
  • The two vertices numbered Ai+3 and Bi+3 will be connected by an edge with a weight of Ci+6.
  • ...

Here, consider the indices of the vertices modulo N. For example, the vertice numbered N is the one numbered 0, and the vertice numbered 2N−1 is the one numbered N−1.

The figure below shows the first seven edges added when N=16,Ai=7,Bi=14,Ci=1:

技术分享图片

After processing all the queries, find the total weight of the edges contained in a minimum spanning tree of the graph.

 

题目大意:对一张 n 个点的空图 G 做 Q 次加边操作,每次给定 Ai ,Bi ,Ci ,然后按照以下规则按顺序连 10 233 条边:(Ai ,Bi ,Ci ),(Bi ,Ai + 1,Ci + 1),(Ai + 1,Bi + 1,Ci + 2),以此类推,点的编号均为 mod n 意义下的,求图 G 的最小生成树。

 

输入格式

The input is given from Standard Input in the following format:

N Q
A1 B1 C1
A2 B2 C2
:
AQ BQ CQ

输出格式

Print the total weight of the edges contained in a minimum spanning tree of the graph.

样例输入

#1

7 1

5 2 1

 

#2

2 1

0 0 1000000000

 

#3

5 3

0 1 10

0 2 10

0 4 10

样例输出

#1

21

The figure below shows the minimum spanning tree of the graph:

技术分享图片

Note that there can be multiple edges connecting the same pair of vertices.

 

#2

1000000001

Also note that there can be self-loops.

 

#3

42

题解

要求一个有无数条边的图的最小生成树,乍一看很吓人,但是乍一想,如果真的是无数条边,再大的空间也存不下。所以肯定有办法可以化无限为有限。

画画图找找规律。

不难发现,加边是有规律的,而且越往后权值越大,也就越不容易被用到。由样例1易发现,由一条边扩展出有限的边数就可以让图连通。那么只要保留让图连通的边就行了。

根据加边的规律,(A,B) 连一条 C 的边,(A,A + i) 连一条 (C + 1 + 2i) 的边,(B,B + i) 连一条 (C + 2 + 2i) 的边。

设di 表示 (i,i + 1) 间的最小权值。

由于一组数据有多组(Ai,Bi,Ci),可能在某条(Ai,Bi,Ci)扩展某条(k,k+1)之前已经有一条(Aj,Bj,Cj)扩展过同一条(k,k+1),则d k= min(dk ,C);

随后再循环di = min(di ,di−1 + 2)。

 

#include <algorithm>
#include <cstdio>
#define LL long long
struct node{
    int u,v;
    LL w;
}g[400005];
int n,m,fa[200005],num;
LL d[200005],tot;
void add(int x,int y,int z)
{
    g[++num].u=x;  g[num].v=y;  g[num].w=z;
    return;
}
LL min(LL x,LL y)
{
    return x<y?x:y;
}
bool cmp(node x,node y)
{
    return x.w<y.w;
}
int find(int x)
{
    if (fa[x]==x) return x;
    return fa[x]=find(fa[x]);
}
void Kruskal()
{
    int i,j,k,fu,fv,cnt;
    for (i=0;i<n;i++)
      fa[i]=i;
    std::sort(g+1,g+num+1,cmp);
    for (i=1;i<=num;i++)
    {
        fu=find(g[i].u);
        fv=find(g[i].v);
        if (fu!=fv)
        {
            fa[fv]=fu;
            //cnt++;
            tot+=g[i].w;
            //if (cnt==n-1) return;
        }
    }  
    return;
}
int main()
{
    int i,j,k,x,y;
    LL z;
    scanf("%d%d",&n,&m);
    for (i=0;i<n;i++)
      d[i]=1e18;
    for (i=1;i<=m;i++)
    {
        scanf("%d%d%lld",&x,&y,&z);
        add(x,y,z);
        if (z+1<d[x]) d[x]=z+1;
        if (z+2<d[y]) d[y]=z+2;
    }
    for (k=1;k<=2;k++)
      for (i=0;i<n;i++)
        d[i]=min(d[i],d[(i+n-1)%n]+2);
    for (i=0;i<n;i++)
      add(i,(i+1)%n,d[i]);
    Kruskal();    
    printf("%lld",tot);
    return 0;      
}

 

【AtCoder - 2134】Zigzag MST

标签:for   扩展   connect   one   example   algorithm   ons   infinite   src   

原文地址:https://www.cnblogs.com/rabbit1103/p/8540644.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!