Bzoj 1726: [Usaco2006 Nov]Roadblocks第二短路 dijkstra,堆,A*,次短路

1726: [Usaco2006 Nov]Roadblocks第二短路

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 969  Solved: 468
[Submit][Status][Discuss]

Description

贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友。贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路。 贝茜所在的乡村有R(1<=R<=100,000)条双向道路,每条路都联结了所有的N(1<=N<=5000)个农场中的某两个。贝茜居住在农场1,她的朋友们居住在农场N(即贝茜每次旅行的目的地)。 贝茜选择的第二短的路径中,可以包含任何一条在最短路中出现的道路,并且,一条路可以重复走多次。当然咯,第二短路的长度必须严格大于最短路(可能有多条)的长度,但它的长度必须不大于所有除最短路外的路径的长度。 

Input

* 第1行: 两个整数,N和R,用空格隔开 

* 第2..R+1行: 每行包含三个用空格隔开的整数A、B和D,表示存在一条长度为 D(1 <= D <= 5000)的路连接农场A和农场B

Output

* 第1行: 输出一个整数,即从农场1到农场N的第二短路的长度 

Sample Input

4 4
1 2 100
2 4 200
2 3 250
3 4 100


Sample Output

450

输出说明:

最短路:1 -> 2 -> 4 (长度为100+200=300)
第二短路:1 -> 2 -> 3 -> 4 (长度为100+250+100=450)

HINT

 

Source

Gold

dijkstra+堆优化+A*

这道题可以正着跑个最短路,倒着跑个最短路,然后枚举每一条边,依次替换即可。

然而我刚学习了A*,就拿A*水了水。

A*果然快的飞起。。。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define MAXN 5010
  4 #define MAXM 100010
  5 #define INF 1e9
  6 struct node
  7 {
  8     int begin,end,value,next;
  9 }edge[2*MAXM];
 10 int cnt,Head[MAXN],cdl,pos[MAXN],Heap[MAXN*2],Heap1[MAXN*2],dis[MAXN],n,SIZE,Time[MAXN];
 11 void addedge(int bb,int ee,int vv)
 12 {
 13     edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].value=vv;edge[cnt].next=Head[bb];Head[bb]=cnt;
 14 }
 15 void addedge1(int bb,int ee,int vv)
 16 {
 17     addedge(bb,ee,vv);addedge(ee,bb,vv);
 18 }
 19 int read()
 20 {
 21     int s=0,fh=1;char ch=getchar();
 22     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
 23     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
 24     return s*fh;
 25 }
 26 void Push1(int k)
 27 {
 28     int now=k,root;
 29     while(now>1)
 30     {
 31         root=now/2;
 32         if(dis[Heap[root]]<=dis[Heap[now]])return;
 33         swap(Heap[root],Heap[now]);
 34         swap(pos[Heap[root]],pos[Heap[now]]);
 35         now=root;
 36     }
 37 }
 38 void Insert(int k)
 39 {
 40     Heap[++SIZE]=k;pos[k]=SIZE;Push1(SIZE);
 41 }
 42 void Pop1(int k)
 43 {
 44     int now,root=k;
 45     pos[Heap[k]]=0;Heap[k]=Heap[SIZE--];if(SIZE>0)pos[Heap[k]]=k;
 46     while(root<=SIZE/2)
 47     {
 48         now=root*2;
 49         if(now<SIZE&&dis[Heap[now+1]]<dis[Heap[now]])now++;
 50         if(dis[Heap[root]]<=dis[Heap[now]])return;
 51         swap(Heap[root],Heap[now]);
 52         swap(pos[Heap[root]],pos[Heap[now]]);
 53         root=now;
 54     }
 55 }
 56 void dijkstra(int start)
 57 {
 58     int i,u,v;
 59     for(i=1;i<=n;i++)dis[i]=INF;dis[start]=0;
 60     for(i=1;i<=n;i++)Insert(i);
 61     while(SIZE>0)
 62     {
 63         u=Heap[1];Pop1(pos[u]);
 64         for(i=Head[u];i!=-1;i=edge[i].next)
 65         {
 66             v=edge[i].end;
 67             if(dis[v]>dis[u]+edge[i].value){dis[v]=dis[u]+edge[i].value;Push1(pos[v]);}
 68         }
 69     }
 70 }
 71 void Push2(int k,int k1)
 72 {
 73     int now,root;
 74     Heap[++SIZE]=k;Heap1[SIZE]=k1;now=SIZE;
 75     while(now>1)
 76     {
 77         root=now/2;
 78         if(Heap1[root]<=Heap1[now])return;
 79         swap(Heap[root],Heap[now]);
 80         swap(Heap1[root],Heap1[now]);
 81         now=root;
 82     }
 83 }
 84 void Pop2()
 85 {
 86     int now,root;
 87     Heap[1]=Heap[SIZE];Heap1[1]=Heap1[SIZE--];root=1;
 88     while(root<=SIZE/2)
 89     {
 90         now=root*2;
 91         if(now<SIZE&&Heap1[now+1]<Heap1[now])now++;
 92         if(Heap1[root]<=Heap1[now])return;
 93         swap(Heap[root],Heap[now]);
 94         swap(Heap1[root],Heap1[now]);
 95         root=now;
 96     }
 97 }
 98 void astar(int start)
 99 {
100     int u1,u2,i,v;
101     Push2(start,dis[start]);
102     while(SIZE>0)
103     {
104         u1=Heap[1];u2=Heap1[1];Pop2();
105         Time[u1]++;
106         if(u1==n&&Time[u1]==2){cdl=u2;return;}
107         if(Time[u1]>2)continue;
108         for(i=Head[u1];i!=-1;i=edge[i].next)
109         {
110             v=edge[i].end;
111             Push2(v,u2-dis[u1]+dis[v]+edge[i].value);
112         }
113     }
114 }
115 int main()
116 {
117     freopen("block.in","r",stdin);
118     freopen("block.out","w",stdout);
119     int bb,ee,vv,m,i;
120     n=read();m=read();
121     memset(Head,-1,sizeof(Head));cnt=1;
122     for(i=1;i<=m;i++)
123     {
124         bb=read();ee=read();vv=read();
125         addedge1(ee,bb,vv);
126     }
127     dijkstra(n);
128     cdl=0;SIZE=0;
129     astar(1);
130     printf("%d",cdl);
131     fclose(stdin);
132     fclose(stdout);
133     return 0;
134 }

 

posted @ 2016-03-30 16:30  微弱的世界  阅读(197)  评论(0编辑  收藏  举报