HDU4435

来源:互联网 发布:洛基权杖淘宝网 编辑:程序博客网 时间:2024/05/23 15:07

Problem : charge-station
Source : 2012 Asia Tianjin Regional Contest
Description :

给你N个点的坐标,现在有一个人开着一辆车从1城市出发,要遍历所有的城市并且回到1城市。但是,车子需要加油,所以要在N个点中的某些城市建立加油站。车子开了D公里就需要加油,并且加满油后可以再跑D公里。问最小费用是多少。在Ti建加油站的费用是2i1

Solution :

这道题在模拟赛的时候我们队没有做出来,哎。首先,要明确两点,在Ti城市建加油站不如在1toTi1,那么我们就从N到2贪心枚举每个城市建还是不建加油站;如果从1城市走到一个加油站,那么这就相当于起点,从这个点能走到其他点并且回来。那么就是可行的。这样我们的问题就变成了求解,每个点到最近加油站的问题,这个可以用bfs从1城市开始搜索,我们把加油站放进队列,如果扩展出的结点到当前点的距离小于D并且这个点还不是被加入进加油站队列的点,那么我们就比较距离,并且这个点是个加油站而且没进队列,我们就把它加入队列去扩展更多的点。最后判断的时候我们只需要这样:这个点是加油站,但是没有进队列,也就是不可达;或者这个点不是加油站,并且到最近加油站的距离的2倍大于D,那么它也是不行的。

Code(JAVA) :

import java.util.Scanner;public class Main {    Scanner cin = new Scanner(System.in);    final static int M = 100 + 50;    final static int INF = 0x3f3f3f3f;    int n, d;    int[][] map = new int[M][M];    Point[] points = new Point[M];    int[] ans = new int[M];    int[] dis = new int[M];    boolean[] used = new boolean[M];    int[] que = new int[M * M * M];    int head, top;    int distance(Point a, Point b) {        return (int) Math.ceil(Math.sqrt((a.x - b.x) * (a.x - b.x)                + (a.y - b.y) * (a.y - b.y)));    }    boolean deal() {        for (int i = 1; i <= n; i++) {            if (ans[i] == 1)                dis[i] = 0;            else                dis[i] = INF;            used[i] = false;        }        head = top = 0;        que[top++] = 1;        used[1] = true;        while (head != top) {            int pre = que[head++];            for (int i = 1; i <= n; i++)                if (map[pre][i] <= d && !used[i]) {                    dis[i] = Math.min(dis[i], dis[pre] + map[pre][i]);                    if (ans[i] == 1) {                        que[top++] = i;                        used[i] = true;                    }                }        }        for (int i = 1; i <= n; i++)            if ((ans[i] == 1 && used[i] == false)                    || (ans[i] == 0 && dis[i] * 2 > d))                return false;        return true;    }    public Main() {        while (cin.hasNext()) {            n = cin.nextInt();            d = cin.nextInt();            for (int i = 1; i <= n; i++)                points[i] = new Point(cin.nextInt(), cin.nextInt());            for (int i = 1; i <= n; i++)                for (int j = i; j <= n; j++)                    map[i][j] = map[j][i] = distance(points[i], points[j]);            for (int i = 0; i < M; i++)                ans[i] = 1;            if (!deal()) {                System.out.println(-1);                continue;            }            for (int i = n; i >= 2; i--) {                ans[i] = 0;                if (!deal())                    ans[i] = 1;            }            int i;            for (i = n; ans[i] == 0 && i >= 1; i--)                ;            for (int j = i; j >= 1; j--)                System.out.print(ans[j]);            System.out.println();        }    }    public static void main(String[] args) {        new Main();    }}class Point {    int x, y;    Point() {    }    Point(int x, int y) {        this.x = x;        this.y = y;    }}
0 0
原创粉丝点击