2162번: 선분 그룹
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static class Line{
long x1,y1,x2,y2;
public Line(long x1, long y1, long x2, long y2){
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
}
}
static int[] parent;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int n = Integer.parseInt(st.nextToken());
Line[] nodelist = new Line[n+1];
parent = new int[n+1];
for(int i = 1; i<n+1; i++){
parent[i] = i;
}
for(int i = 1; i<n+1; i++){
st = new StringTokenizer(br.readLine(), " ");
long x1 = Long.parseLong(st.nextToken());
long y1 = Long.parseLong(st.nextToken());
long x2 = Long.parseLong(st.nextToken());
long y2 = Long.parseLong(st.nextToken());
nodelist[i] = new Line(x1, y1, x2, y2);
}
for(int i = 1; i<n+1; i++){
for(int j = 1; j<n+1; j++){
if(find(i) != find(j)){
if(cross(nodelist[i], nodelist[j])){
union(i,j);
}
}
}
}
int[] cnt = new int[n+1];
int max = 0;
int size = 0;
for(int i = 1; i<n+1; i++){
cnt[parent[i]]++;
}
for(int i = 1; i<n+1; i++){
if(max < cnt[i]) max = cnt[i];
if(cnt[i] != 0) size++;
}
System.out.println(size);
System.out.println(max);
}
public static boolean cross(Line line1, Line line2){
//a<0 또는 a = 0
long a = ccw(line1.x1, line1.y1, line1.x2, line1.y2, line2.x1, line2.y1) * ccw(line1.x1, line1.y1, line1.x2, line1.y2, line2.x2, line2.y2);
//b<0 또는 b = 0
long b = ccw(line2.x1, line2.y1, line2.x2, line2.y2, line1.x1, line1.y1) * ccw(line2.x1, line2.y1, line2.x2, line2.y2, line1.x2, line1.y2);
if(a == 0 && b == 0)return overlap(line1, line2);
if(a<=0 && b<=0) return true;
return false;
}
public static boolean overlap(Line line1, Line line2){
if(Math.max(line1.x1, line1.x2) < Math.min(line2.x1, line2.x2)) return false;
if(Math.max(line1.y1, line1.y2) < Math.min(line2.y1, line2.y2)) return false;
if(Math.max(line2.x1, line2.x2) < Math.min(line1.x1, line1.x2)) return false;
if(Math.max(line2.y1, line2.y2) < Math.min(line1.y1, line1.y2)) return false;
return true;
}
public static int ccw(long x1, long y1, long x2, long y2, long x3, long y3){
long result = (x1*y2+x2*y3+x3*y1) - (x2*y1+x3*y2+x1*y3);
if(result>0) return -1;
else if(result == 0) return 0;
else return 1;
}
public static int find(int a){
if(parent[a] == a) return a;
return parent[a] = find(parent[a]);
}
public static void union(int a, int b){
int parent_a = find(a);
int parent_b = find(b);
if(parent_a != parent_b){
if (parent_a > parent_b) {
parent[parent_a] = parent_b;
} else {
parent[parent_b] = parent_a;
}
}
}
}