Random Spanning Tree problem solution P5036 []

This problem could have been cattle off network simulation race problem, because I went wrong when the exam, think kruskal, and found not do, so I put the title changed, the changed kruskal can do, but still be wjyyy people experience problems with the original method easily get rid of QAQ, so I decided to change the subject program output2333

More than purely nonsense

After reading the title, identify problems in physical connectivity up to block number, think about it hard to find a positive push forward, push it backwards chant. We first assume that there is no tree edge, the current block in communication with a $ $ n-th, and now we want to add $ n-1 $ edges in this $ $ n-th points. Based on the definition of the communication block, we can find: If an edge connecting two points of different colors, then the current edge has no effect on the current communication block number, the same two points when the color of an edge connector, the current block number of the communication We need to reduce the $ 1 $.

So practice this question is very clear: you can not even enumerate all of the first side (if you think about it you will find a little if multiple enumerations each number can be found on all sides of), two points connected by an edge if the color are different, if the current edge connector, its contribution to the number of connected blocks is $ 1 $, $ 0 or $ contribution, and a sequence in accordance with the subject claim row, while kruskal run on the line. (Is not that simple, I think so too QAQ)

code show as below:

#include<bits/stdc++.h>
#define REP(i,a,b) for (register int i(a);i<=(b);i++)
namespace fast_IO {
    const int IN_LEN=10000000,OUT_LEN=10000000;
    char ibuf[IN_LEN],obuf[OUT_LEN],*ih=ibuf+IN_LEN,*oh=obuf;
    char *lastin=ibuf+IN_LEN;
    const char *lastout=ibuf+OUT_LEN-1;
    inline char getchar_() {
        if(ih==lastin)lastin=ibuf+fread(ibuf,1,IN_LEN,stdin),ih=ibuf;
        return (*ih++);
    } inline void putchar_(const char x) {
        if(ih==lastout)fwrite(obuf,1,oh-obuf,stdout),oh=obuf;
        *oh++=x;
    } inline void flush() {
        fwrite(obuf, 1, oh - obuf, stdout);
    }
}
using namespace fast_IO;
using namespace std;
template <typename T>
inline void Read(T&x) {
    char cu=getchar();
    x=0;
    bool fla=0;
    while(!isdigit(cu)) {
        if(cu=='-')fla=1;
        cu=getchar();
    }
    while(isdigit(cu))x=x*10+cu-'0',cu=getchar();
    if(fla)x=-x;
}
template <typename T>
void printe(const T x) {
    if(x>=10)printe(x/10);
    putchar(x%10+'0');
}
template <typename T>
inline void Write(const T x) {
    if(x<0)putchar('-'),printe(-x);
    else printe(x);
}
//以上是快速输入输出(可以忽略)
long long a,b,n,Cnt,Num,Ans,c[5000010],Fa[5000010];
struct Node{
    int x,y,v;
}k[100000010];
int Find(int x){
    while(Fa[x]!=x) x=Fa[x]=Fa[Fa[x]];
    return x;   
}
bool Cmp(Node a,Node b){
    if(a.v!=b.v){
        return a.v>b.v;
    }
    else{
        if((a.x+a.y)!=(b.x+b.y)){
            return (a.x+a.y)<(b.x+b.y);
        }
        else{
            return a.x<b.x;
        }
    }    
}
int main() {
    Read(n);
    REP(i,1,n) {
        Read(c[i]);
    }
    REP(i,1,n>>1) {
        REP(j,2,n/i) {
            k[++Cnt].x=i;
            k[Cnt].y=i*j;
            if(c[i]!=c[i*j]){
                k[Cnt].v=1;
            }
        }
    }
    for (int i=1;i<=n;i++)
        Fa[i]=i;
    sort(k+1,k+Cnt+1,Cmp); 
    for (int i=1;i<=Cnt;i++){
            a=0;
            b=0;
            a=Find(k[i].x);
            b=Find(k[i].y);
            if (a==b)
                continue;
            Write(k[i].x);
            putchar(' ');   
            Write(k[i].y);
            putchar('\n');
            Fa[b]=a;
        }
return flush(),0;//Fast IO专用结尾
}

Guess you like

Origin www.cnblogs.com/zhudafu/p/11483057.html