hdu 3873 Invade the Mars(自写堆优化Dijkstra)

来源:互联网 发布:pdf.js 编辑:程序博客网 时间:2024/05/11 19:07

题意:以城市1为出发点,城市n为目的地,有若干条限制:要首先攻占城市a才能攻占城市b,问攻占城市n所需的最短时间。

从源点到任意一点的最短路受两个条件的限制:一是源点到自己的最短路,而是源点到限制点的最短路,即限制点最短路f[c] = Math.max(f[c], d[a]);最短路d[c] = Math.max(d[c], f[c]);

因此要确定所有限制点的最短路后才能使用该点松弛其它顶点。充分利用Dijkstra的最优子结构的性质,当一个点的所有限制点的最短路都确定时再将此点放入队列中,参与松弛过程。

public class InvadeMars {int maxn = 3010, maxm = 70010;long inf = 1l<<50;class node {int be, ne;long val;node(int b, int e, long v) {be = b;ne = e;val = v;}}class HEAP {int n;long arr[] = new long[maxn];int hp[] = new int[maxn], idx[] = new int[maxn];void build(long a[], int n) {this.n = n;for (int i = 1; i <= n; i++) {arr[i] = a[i];hp[i] = idx[i] = i;}for (int i = n / 2; i > 0; i--)heapify(i);}void heapify(int i) {int l = i * 2, r = i * 2 + 1, k = i;if (l <= n && arr[l] < arr[k])k = l;if (r <= n && arr[r] < arr[k])k = r;if (k != i) {swap(i, k);heapify(k);}}void swap(int i, int j) {idx[hp[i]] = j;idx[hp[j]] = i;long temp = hp[i];hp[i] = hp[j];hp[j] =(int)temp;temp = arr[i];arr[i] = arr[j];arr[j] = temp;}void decreasekey(int i, long v) {i = idx[i];arr[i] = v;while (i > 1 && arr[i] < arr[i / 2]) {swap(i, i / 2);i /= 2;}}int poll() {int ans =hp[1]; idx[hp[n]] = 1;hp[1] = hp[n];arr[1] = arr[n--];heapify(1);return ans;}}class Dijkstra {// 节点编号1--n !!int E[] = new int[maxn], len, n;node buf[] = new node[maxm];HEAP hp = new HEAP();void add(int a, int b, long v) {buf[len] = new node(b, E[a], v);E[a] = len++;}void init(int n) {len = 0;this.n = n;Arrays.fill(E, -1);}long d[] = new long[maxn], f[] = new long[maxn];boolean vis[]=new boolean[maxn];void solve(int s) {Arrays.fill(d, inf);Arrays.fill(f, 0);Arrays.fill(vis,false);hp.build(d, n);d[s] = 0;hp.decreasekey(s, 0);while (hp.n > 0) {int a = hp.poll();if(vis[a])continue;          vis[a]=true;for (int j = EE[a]; j != -1; j = bb[j].ne) {int c = bb[j].be;f[c] = Math.max(f[c], d[a]);if (--dgr[c] == 0&&d[c]!=inf){d[c] = Math.max(d[c], f[c]);hp.decreasekey(c, d[c]);}}for (int i = E[a]; i != -1; i = buf[i].ne) {int b = buf[i].be;if (d[a] + buf[i].val < d[b]) {d[b]=d[a] + buf[i].val;if (dgr[b] == 0)hp.decreasekey(b, d[b]);}}}}}node bb[] = new node[maxm];Dijkstra dij = new Dijkstra();int EE[] = new int[maxn], len, n;int dgr[] = new int[maxn];StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));int nextInt() throws IOException {in.nextToken();return (int) in.nval;}void init() {dij.init(n);len = 0;Arrays.fill(EE, -1);Arrays.fill(dgr, 0);}void add(int a, int b) {bb[len] = new node(b, EE[a], 0);EE[a] = len++;}void run() throws IOException {int cas = nextInt();while (cas-- > 0) {n = nextInt();init();int m = nextInt();while (m-- > 0)dij.add(nextInt(), nextInt(), nextInt());for (int i = 1; i <= n; i++) {int k = nextInt();while (k-- > 0) {int b = nextInt();dgr[i]++;add(b, i);}}dij.solve(1);System.out.println(dij.d[n]);}}public static void main(String[] args) throws IOException {new InvadeMars().run();}}