힌트를 얻기 위해 검색했다.
BFS와 이진탐색을 함께 사용해야 한다는 내용을 보았다.
BFS와 이진탐색을 어떻게? —>
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main{
public static int n,m;
public static int start,end;
public static ArrayList<int[]>[] graph;
public static boolean[] visit;
public static int max=0; // 입력받은 중량 중 최대 중량
public static int ans=1; // 성공가능 중량 중 최대 중량
public static void Setting() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
graph = new ArrayList[n+1];
visit = new boolean[n+1];
int i=0;
for(i=0;i<n;i++){
graph[i]= new ArrayList<>();
}
for(i=0;i<m;i++){
st = new StringTokenizer(br.readLine());
int v1 = Integer.parseInt(st.nextToken())-1;
int v2 = Integer.parseInt(st.nextToken())-1;
int w = Integer.parseInt(st.nextToken());
graph[v1].add(new int[]{v2,w});
graph[v2].add(new int[]{v1,w});
if(w>max) max = w;
}
st = new StringTokenizer(br.readLine());
start = Integer.parseInt(st.nextToken())-1;
end = Integer.parseInt(st.nextToken())-1;
}
// 0 1
public static void binSearch(int left,int right){
int mid =0;
while(left<=right){
mid = (left+right)/2;
if(bfs(mid)){
ans = mid;
left = mid+1;
}else{
right = mid-1;
}
}
}
// 하나라도 성공시 true
// 실패시 false
public static boolean bfs(int limit){
Queue<Integer> q = new LinkedList<>();
Arrays.fill(visit,false);
q.add(start);
visit[start]=true;
while(q.isEmpty()==false){
int cur = q.poll();
if(cur==end){
return true;
}
for(int i=0;i<graph[cur].size();i++){
int[] next = graph[cur].get(i);
if(visit[next[0]]) continue;
if(next[1]<limit) continue;
q.add(next[0]);
visit[next[0]] = true;
}
}
return false;
}
public static void main(String[] args) throws IOException{
Setting();
binSearch(0,max);
System.out.println(ans);
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class main {
public static int n, m; // n 은 vertex 개수, m은 edge 개수
public static int start, end; // 연결되어야 하는 두 공장
public static int[] root;
public static int max = 0; // 입력받은 중량 중 최대 중량
public static Queue<int[]> pq = new PriorityQueue<>(new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o2[2] - o1[2];
}
});
public static void Setting() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
// root table init
root = new int[n];
for(int i=0;i<n;i++)
root[i]=i;
// edge info
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int v1 = Integer.parseInt(st.nextToken()) - 1;
int v2 = Integer.parseInt(st.nextToken()) - 1;
int w = Integer.parseInt(st.nextToken());
pq.add(new int[]{v1,v2,w});
}
st = new StringTokenizer(br.readLine());
start = Integer.parseInt(st.nextToken()) - 1;
end = Integer.parseInt(st.nextToken()) - 1;
}
public static void solve(){
while(pq.isEmpty()==false) {
// edge extract
int[] cur = pq.poll();
// two nodes connected by this edge to be checked if they already belong to the same graph
if (union(cur[0], cur[1]) == true) continue;
// 새로 union 시켜 줄 때(기존에 두 노드가 같은 그래프가 아니었던 경우) 마다, start,end가 같은 그래프 소속이 되었는지 확인
// 같은 그래프 소속이라면, 최대 중량을 찾은 것 --> 종료
if (sameGraph(start, end) == false) continue;
max = cur[2];
break;
}
}
// a가 속한 그래프의 root
// 좀 더 개선한 find --> 다음에 a--root까지 의 path에 있는 상위 intermediate node들에 대한 find 속도가 개선된다.
public static int find(int a){
if(root[a]==a)return a;
return root[a]= find(root[a]);
}
// a,b가 이미 같은 그래프 소속 --> return true;
// 다른 소속 --> union 시켜주고, 이전에는 같은 그래프 아니었으니 false.
public static boolean union(int a,int b){
int ra = find(a);
int rb = find(b);
if(ra==rb) return true;
else if(ra<rb) root[ra]=rb;
else root[rb]=ra;
return false;
}
public static boolean sameGraph(int a, int b){
int ra = find(a);
int rb = find(b);
if(ra==rb) return true;
else return false;
}
public static void main(String[] args) throws IOException {
Setting();
solve();
System.out.println(max);
}
}
첫 번째 풀이보다 효율은 더 좋게 나왔다.