Advertisement
Guest User

TSP

a guest
Jan 18th, 2012
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.16 KB | None | 0 0
  1. import java.io.*;
  2. import java.util.*;
  3. import java.math.*;
  4. import java.awt.geom.*;
  5.  
  6. public class Solution implements Runnable {
  7.  
  8.     public static void main(String[] args) throws Exception {
  9.         new Thread(null, new Solution(), "", 1 << 25).start();
  10.     }
  11.  
  12.     BufferedReader in;
  13.     PrintWriter out;
  14.     StringTokenizer st;
  15.  
  16.     final String fname = "";
  17.  
  18.     private String next() throws Exception {
  19.         if (st == null || !st.hasMoreElements())
  20.             st = new StringTokenizer(in.readLine());
  21.         return st.nextToken();
  22.     }
  23.  
  24.     private int nextInt() throws Exception {
  25.         return Integer.parseInt(next());
  26.     }
  27.  
  28.     private long nextLong() throws Exception {
  29.         return Long.parseLong(next());
  30.     }
  31.  
  32.     private double nextDouble() throws Exception {
  33.         return Double.parseDouble(next());
  34.     }
  35.  
  36.     public void run() {
  37.         try {
  38.             in = new BufferedReader(new InputStreamReader(System.in));
  39.             out = new PrintWriter(new OutputStreamWriter(System.out));
  40.             solve();
  41.         } catch (Exception ex) {
  42.             throw new RuntimeException(ex);
  43.         } finally {
  44.             out.close();
  45.         }
  46.     }
  47.    
  48.     static final double EPS = 1e-14;
  49.    
  50.     class Point implements Comparable<Point> {
  51.         double x,y;
  52.         int index;
  53.        
  54.         public Point(double x, double y, int index) {
  55.             this.x = x;
  56.             this.y = y;
  57.             this.index = index;
  58.         }
  59.        
  60.         @Override
  61.         public int compareTo(Point o) {
  62.             if (this.x < o.x) return -1;
  63.             if (this.x > o.x) return 1;
  64.             if (this.y < o.y) return -1;
  65.             if (this.y > o.y) return 1;
  66.             return 0;
  67.         }
  68.        
  69.     }
  70.    
  71.     double distance (Point a, Point b) {
  72.         return Math.sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
  73.     }
  74.    
  75.     boolean cw (Point a, Point b, Point c) {
  76.         return a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y) < 0;
  77.     }
  78.  
  79.     boolean ccw (Point a, Point b, Point c) {
  80.         return a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y) < 0;
  81.     }
  82.    
  83.     ArrayList<Point> convexHull (ArrayList<Point> a) {
  84.         Collections.sort(a);
  85.         Point p1 = a.get(0);
  86.         Point p2 = a.get(a.size() - 1);
  87.         ArrayList<Point> up = new ArrayList<Solution.Point>();
  88.         ArrayList<Point> down = new ArrayList<Solution.Point>();
  89.         up.add(p1);
  90.         down.add(p1);
  91.         for (int i = 1; i < a.size(); i++) {
  92.             if (i == a.size() - 1 || cw (p1, a.get(i), p2)) {
  93.                 while (up.size() >= 2 && !cw (up.get(up.size() - 2), up.get(up.size() - 1), a.get(i)))
  94.                     up.remove(up.size() - 1);
  95.                 up.add(a.get(i));
  96.             }
  97.             if (i == a.size() - 1 || ccw (p1, a.get(i), p2)) {
  98.                 while (down.size() >= 2 && !ccw (down.get(down.size() - 2), down.get(down.size() - 1), a.get(i)))
  99.                     down.remove(down.size() - 1);
  100.                 down.add(a.get(i));
  101.                
  102.             }
  103.         }
  104.         ArrayList<Point> result = new ArrayList<Solution.Point>();
  105.         for (int i = 0; i < up.size(); i++)
  106.             result.add(up.get(i));
  107.         for (int i = down.size() - 2; i > 0; i--)
  108.             result.add(down.get(i));
  109.         return result;
  110.     }
  111.    
  112.    
  113.     public void solve() throws Exception {
  114.         int n = nextInt();
  115.         ArrayList<Point> a = new ArrayList<Solution.Point>();
  116.         for (int i = 0; i < n; i++) {
  117.             a.add(new Point(nextDouble(), nextDouble(), i));
  118.         }
  119.         ArrayList<Point> convex = convexHull (a);
  120.        
  121.         boolean used [] = new boolean [n];
  122.         for (Point p : convex)
  123.             used[p.index] = true;
  124.        
  125.         int m = convex.size();
  126.        
  127.         for (int k = 0; k < n - m; k++) {
  128.             int besti = -1;
  129.             int bestj = -1;
  130.             double bestDist = 1e9;
  131.             for (int i = 0; i < n; i++) {
  132.                 if (!used[a.get(i).index]) {
  133.                     double px = a.get(i).x;
  134.                     double py = a.get(i).y;
  135.                     for (int j = 0; j < convex.size(); j++) {
  136.                         int jj = (j + 1) % convex.size();
  137.                         double x1 = convex.get(j).x;
  138.                         double y1 = convex.get(j).y;
  139.                         double x2 = convex.get(jj).x;
  140.                         double y2 = convex.get(jj).y;
  141.                         double dist = Line2D.ptSegDist(x1, y1, x2, y2, px, py);
  142.                         if (dist < bestDist) {
  143.                             bestDist = dist;
  144.                             besti = i;
  145.                             bestj = jj;
  146.                         }
  147.                     }
  148.                 }
  149.             }
  150.             convex.add(bestj, a.get(besti));
  151.             used [a.get(besti).index] = true;
  152.         }
  153.        
  154.         double result = 0.0;
  155.         for (int i = 0; i < n; i++) {
  156.             int j = (i + 1) % n;
  157.             result += distance (convex.get(i), convex.get(j));
  158.         }
  159.        
  160.         out.printf("%.14f\n", result);
  161.         for (int i = 0; i < n; i++) {
  162.             out.print(convex.get(i).index + " ");
  163.         }
  164.        
  165.     }
  166.  
  167.  
  168. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement