您的位置:首页 > 其它

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

2012-08-14 10:12 375 查看
题意:以城市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
] = 1;
hp[1] = hp
;
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
);
}
}
public static void main(String[] args) throws IOException {
new InvadeMars().run();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: