AtCoder ABC 229E - Graph Destruction 解題心得( 題目 )

解題概念:併查集(Disjoint set)

解題方法:首先可以先把問題轉換成依序從n、n-1...加點和邊上去,加一個點會使答案多1,而加上邊的方式可用併查集,如果兩個點的爸爸不同代表他們處不同集合,我們就把他合併,並且將答案少1,另外這裡使用了路徑壓縮的技巧優化。

Java參考程式碼(有更好意見可留言於下方,謝謝!)

//Author:En Chi Tsung(欉恩祁)

//Date:2021/12/12

import java.util.*;

import java.io.*;

public class Main {

    public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

    public static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));

    public static int ret,r;

    public static int top,ans=0;

    public static int[] dsu=new int[200005];

    public static void main(String[] args) throws Exception{

        int ra,rb,id=-1;

        final int n=orz();

        final int m=orz();

        pair[] edge=new pair[m];

        Stack<Integer> answ=new Stack<>();

        for(int i=0;i<m;i++) {

            ra=orz();

            rb=orz();

            if(ra>rb) {

                edge[i]=new pair(rb,ra);

            }

            else {

                edge[i]=new pair(ra,rb);

            }

        }

        Arrays.sort(edge,new Comparator<pair>() {

            public int compare(pair f,pair s) {

                if(f.x>s.x)return -1;

                if(f.x<s.x)return 1;

                return 0;

            }

        });


        answ.push(0);

        for(int i=n;i>1;i--) {

            ans++;

            while(id!=m-1&&edge[id+1].x>=i) {

                union(edge[id+1].x,edge[id+1].y);

                id++;

            }

            answ.push(ans);

        }

        while(!answ.isEmpty()) {

            bw.write(answ.pop()+"\n");

        }

        bw.flush();

    }

    

    public static void union(int x,int y) {

        query(x);

        int xset=top;

        query(y);

        int yset=top;

        if(xset==yset)return;

        ans--;

        dsu[yset]=xset;

    }

    

    public static void query(int x) {

        if(dsu[x]==0) {

            top=x;

            return;

        }

        query(dsu[x]);

        dsu[x]=top;

    }

    public static int orz() throws Exception{

        ret=0;

        r=br.read();

        while(r>47&&r<58) {

            ret*=10;

            ret+=(r&15);

            r=br.read();

        }

        return ret;

    }

}

 

class pair{

    int x,y;

    pair(int a,int b){

        x=a;

        y=b;

    }

}

 

 

文章標籤
全站熱搜
創作者介紹
創作者 En Chi Tsung 的頭像
En Chi Tsung

阿祁的部落格

En Chi Tsung 發表在 痞客邦 留言(0) 人氣(1)