讨论 / 请教……为什么写线段树优化最短路会退化……
fts96 2012-10-14 00:41:00
点我顶贴 收藏 删除
写了个线段树优化dijkstra……结果诡异地退化到两百秒都不出解……谁能帮忙看下为什么会这样……

#include <stdio.h>

#include <iostream>

#include <stdlib.h>

#include <queue>

#define MAXN 300010

#define MAXM 1200000

#define inf 200000000

using namespace std;

int t[MAXM],w[MAXM],nex[MAXM],d[MAXN],v[MAXN],pos[MAXN],box[MAXN];

int l[2*MAXN],r[2*MAXN],mi[2*MAXN],cur[2*MAXN];

int sum,n,head,tail,i,hl;

void add_edge(int ss,int tt,int ww)

{

t[++sum]=tt;

w[sum]=ww;

nex[sum]=box[ss];

box[ss]=sum;

}

void unionnode(int t,int a,int b)

{

if (mi[a]<mi[b])

{

mi[t]=mi[a];

cur[t]=cur[a];

}

else

{

mi[t]=mi[b];

cur[t]=cur[b];

}

}

void build_tree(int left,int right,int loc)

{

l[loc]=left;

r[loc]=right;

if (left==right)

{

mi[loc]=d[left];

pos[left]=loc;

cur[loc]=left;

}

else

{

build_tree(left,(left+right)/2,2*loc);

build_tree((left+right)/2+1,right,2*loc+1);

unionnode(loc,loc*2,loc*2+1);

}

}

void relax(int u,int v,int w)

{

int i;

if (mi[pos[v]]>mi[pos[u]]+w)

{

mi[pos[v]]=mi[pos[u]]+w;

i=pos[v];

while (i!=1)

{

unionnode(i/2,i,i^1);

i/=2;

}

}

}

void dijkstra(int s,int to)

{

int p,i,j,tt,br;

d[s]=0;

build_tree(1,n,1);

tt=cur[1];

while (tt!=to)

{

p=box[tt];

while (p)

{

relax(tt,t[p],w[p]);

p=nex[p];

}

i=pos[tt];

mi[i]=inf;

while (i!=1)

{

unionnode(i/2,i,i^1);

i/=2;

}

tt=cur[1];

}

printf("%d\n",mi[1]);

}

void init()

{

int i,j,ww;

sum=0;

scanf("%d",&n);

for (i=1;i<=n*n+2;++i)

{

d[i]=inf;

box[i]=0;

}

for (i=1;i<=n+1;++i)

{

for (j=1;j<=n;++j)

{

scanf("%d",&ww);

if (i==1) add_edge(n*n+1,j,ww);

else if (i==n+1) add_edge((i-2)*n+j,n*n+2,ww);

else add_edge((i-2)*n+j,(i-1)*n+j,ww);

}

}

for (i=1;i<=n;++i)

{

for (j=1;j<=n+1;++j)

{

scanf("%d",&ww);

if (j==1) add_edge((i-1)*n+1,n*n+2,ww);

else if (j==n+1) add_edge(n*n+1,i*n,ww);

else add_edge((i-1)*n+j,(i-1)*n+j-1,ww);

}

}

for (i=1;i<=n+1;++i)

{

for (j=1;j<=n;++j)

{

scanf("%d",&ww);

if (i==1) add_edge(j,n*n+1,ww);

else if (i==n+1) add_edge(n*n+2,(i-2)*n+j,ww);

else add_edge((i-1)*n+j,(i-2)*n+j,ww);

}

}

for (i=1;i<=n;++i)

{

for (j=1;j<=n+1;++j)

{

scanf("%d",&ww);

if (j==1) add_edge(n*n+2,(i-1)*n+1,ww);

else if (j==n+1) add_edge(i*n,n*n+1,ww);

else add_edge((i-1)*n+j-1,(i-1)*n+j,ww);

}

}

n=n*n+2;

}

int main()

{

freopen("in.txt","r",stdin);

freopen("out.txt","w",stdout);

init();

dijkstra(n-1,n);

return 0;

}

查看更多回复
提交回复