Atcoder2134 Zigzag MST

Problem Description

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 *C**i* will be given, and we will add infinitely many edges to the graph as follows:

  • The two vertices numbered *A**i* and *B**i* will be connected by an edge with a weight of *C**i*.
  • The two vertices numbered *B**i* 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 *C**i*+2.
  • The two vertices numbered Bi+1 and Ai+2 will be connected by an edge with a weight of *C**i*+3.
  • The two vertices numbered Ai+2 and Bi+2 will be connected by an edge with a weight of *C**i*+4.
  • The two vertices numbered Bi+2 and Ai+3 will be connected by an edge with a weight of *C**i*+5.
  • The two vertices numbered Ai+3 and Bi+3 will be connected by an edge with a weight of *C**i*+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.

Input Format

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

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

Output Format

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

Sample input

7 1
5 2 1

Sample Output

21

Resolve

Consider the equivalent replacement. For a plus side operation, weights since (x, y) is smaller than (y, x + 1) weights, consider the process kruskal is, when considering the edge (y, x + 1, z + 1) , and x, y has a certain block in the communication. Thus, we can (y, x + 1, z + 1) is replaced with equivalent (x, x + 1, z + 1). Similarly, (x + 1, y + 1, z + 2) may be replaced by (y, y + 1, z + 2). After such replacement, we found that two rings produce a plus side operation will map to a path starting from the ring is c + 1, c + 3, c + 5, ......, b is the path to a starting point of the ring is c + 2, c + 4, c + 6, ......, as well as (a, b, c) side. Set \ (F [i] \) represents the edges between i-1 to i smallest, we can use the maximum prefix similar way, obtain each F:
\ [F [i +. 1] = max (f [i + 1],
f [i]) \] Note that \ (n-F [+. 1] = F [. 1] \) , because there may be updated at a later point in the circle after the update, so we want to update twice.

Finally, figure only q + n edges, with a maximum spanning tree to find Kruskal.

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define int long long
#define N 400002
using namespace std;
struct edge{
    int u,v,w;
}e[N];
int n,q,i,f[N],num,fa[N];
int read()
{
    char c=getchar();
    int w=0;
    while(c<'0'||c>'9') c=getchar();
    while(c<='9'&&c>='0'){
        w=w*10+c-'0';
        c=getchar();
    }
    return w;
}
int my_comp(const edge &x,const edge &y)
{
    return x.w<y.w;
}
int find(int x)
{
    if(x!=fa[x]) fa[x]=find(fa[x]);
    return fa[x];
}
int Kruscal()
{
    for(int i=1;i<=n;i++) fa[i]=i;
    sort(e+1,e+num+1,my_comp);
    int cnt=n,ans=0;
    for(int i=1;i<=num;i++){
        int f1=find(e[i].u),f2=find(e[i].v);
        if(f1!=f2){
            fa[f1]=f2;
            cnt--;
            ans+=e[i].w;
        }
    }
    return ans;
}
signed main()
{
    memset(f,0x3f,sizeof(f));
    n=read();q=read();
    for(i=1;i<=q;i++){
        int a,b,c;
        a=read()+1;b=read()+1;c=read();
        e[++num]=(edge){a,b,c};
        f[a]=min(f[a],c+1);
        f[b]=min(f[b],c+2);
    }
    bool flag=0;
    for(i=1;i<=n;i++){
        f[i%n+1]=min(f[i]+2,f[i%n+1]);
        if(i==n&&!flag) i=0,flag=1;
    }
    for(i=1;i<=n;i++) e[++num]=(edge){i,i%n+1,f[i]};
    cout<<Kruscal()<<endl;
    return 0;
}

Guess you like

Origin www.cnblogs.com/LSlzf/p/11183991.html
MST
MST