제출 #339246

#제출 시각아이디문제언어결과실행 시간메모리
339246KWang31Mergers (JOI19_mergers)Java
56 / 100
3085 ms52388 KiB
import java.io.*; import java.util.*; public class mergers{ static class FastReader { BufferedReader br; StringTokenizer st; public FastReader() { br = new BufferedReader(new InputStreamReader(System.in)); } String next() { while (st == null || !st.hasMoreElements()) { try { st = new StringTokenizer(br.readLine()); } catch (IOException e) { e.printStackTrace(); } } return st.nextToken(); } int nextInt() { return Integer.parseInt(next()); } } public static class Pair implements Comparable<Pair>{ int vtx; int val; public Pair(int a, int b){ this.vtx=a; this.val=b; } public int compareTo(Pair other){ if(this.val<other.val)return -1; if(this.val>other.val)return 1; if(this.vtx<other.vtx)return -1; return 1; } } static int MOD=998244353; static int[] rk, p,siz; static int[] par,dep; public static void main(String[] args){ FastReader br=new FastReader(); int N=br.nextInt(); int M=br.nextInt(); ArrayList<Integer> states[]=new ArrayList[M]; for(int i=0;i<M;i++){states[i]=new ArrayList<>();} ArrayList<Integer> adj[]=new ArrayList[N]; for(int i=0;i<N;i++){adj[i]=new ArrayList<>();} int a,b; for (int i = 0; i < N-1; i++) { a=br.nextInt()-1; b=br.nextInt()-1; adj[a].add(b); adj[b].add(a); } for (int i = 0; i < N; i++) { a=br.nextInt()-1; states[a].add(i); } par=new int[N]; dep=new int[N]; dfs(adj,-1,0); int[] skip=new int[N];//Skipping: avoiding repeated merging for (int i = 0; i < N; i++) { skip[i]=i; } for (int i = 0; i < M; i++) { for (int j = 0; j < states[i].size()-1; j++) { a=states[i].get(j); b=states[i].get(j+1); while(a!=b){ if(dep[a]>=dep[b]){ skip[a]=find(par[a],skip); a=par[a]; }else{ skip[b]=find(par[b],skip); b=par[b]; } } //For each a, we have merged a with its 1st, .., kth ancestor. //They belong to the same state } } //In the end, all vertices of the same state have the same skip //Therefore, after merging, if two vertices don't have some skip, they are not in the same state int[] deg=new int[N]; for (int i = 0; i < N; i++) { for (int j : adj[i]) { if(find(i,skip)!=find(j,skip)){ //Notice in the compressed form, there is only one leader for each state, namely j //If i is adjacent to two vertices with same find, i must have that find too deg[find(i,skip)]++; } } } //System.out.println(Arrays.toString(deg)); int ans=0; for (int i = 0; i < N; i++) { if(deg[i]==1)ans++; } System.out.println((ans+1)/2); //If a state is a leaf, there exist exactly one } public static int find(int x, int[] p){ if(p[x]==x)return x; p[x]=find(p[x],p); return p[x]; } public static void merge(int a, int b) { if(rk[a]<rk[b]) { p[a]=b; siz[b]+=siz[a]; }else if(rk[a]==rk[b]) { p[a]=b; rk[b]++;siz[b]+=siz[a]; }else { p[b]=a; siz[a]+=siz[b]; } } public static void dfs(ArrayList<Integer>[] adj, int p, int v){ for (int c : adj[v]) { if(c==p)continue; dep[c]=dep[v]+1; par[c]=v; dfs(adj,v,c); } } } //Debugging: //Are you sure your algorithm is correct? //Bounds: long //Special cases: n=0,1? //Make sure you remove your debugging code before you submit!

컴파일 시 표준 에러 (stderr) 메시지

Note: mergers.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...