Bzoj 2834: 回家的路 dijkstra,堆优化,分层图,最短路

2834: 回家的路

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 62  Solved: 38
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

2 1
1 2
1 1 2 2

Sample Output

5

HINT

 

N<=20000,M<=100000

 

Source

dijkstra+堆优化+分层图
把所有的横向和纵向分开看。跑最短路即可。
注意:N这么大,不能写N^2建图。要把M个位置去建图。
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define MAXN 20010
  4 #define MAXM 100010
  5 #define INF 1e9
  6 struct NODE
  7 {
  8     int begin,end,value,next;
  9 }edge[6*MAXM+10];
 10 struct node
 11 {
 12     int x,y,id;
 13 }a[MAXM+10];
 14 int cnt,Head[2*MAXM+10],pos[2*MAXM+10],Heap[2*MAXM+10],dis[2*MAXM+10],N,SIZE;
 15 void addedge(int bb,int ee,int vv)
 16 {
 17     edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].value=vv;edge[cnt].next=Head[bb];Head[bb]=cnt;
 18 }
 19 void addedge1(int bb,int ee,int vv)
 20 {
 21     addedge(bb,ee,vv);addedge(ee,bb,vv);
 22 }
 23 int read()
 24 {
 25     int s=0,fh=1;char ch=getchar();
 26     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
 27     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
 28     return s*fh;
 29 }
 30 //int xy(int x,int y){return (x-1)*n+y;}
 31 void Push1(int k)
 32 {
 33     int now=k,root;
 34     while(now>1)
 35     {
 36         root=now/2;
 37         if(dis[Heap[root]]<=dis[Heap[now]])return;
 38         swap(Heap[root],Heap[now]);
 39         swap(pos[Heap[root]],pos[Heap[now]]);
 40         now=root;
 41     }
 42 }
 43 void Insert(int k)
 44 {
 45     Heap[++SIZE]=k;pos[k]=SIZE;Push1(SIZE);
 46 }
 47 void Pop1(int k)
 48 {
 49     int now,root=k;
 50     pos[Heap[k]]=0;Heap[k]=Heap[SIZE--];if(SIZE>0)pos[Heap[k]]=k;
 51     while(root<=SIZE/2)
 52     {
 53         now=root*2;
 54         if(now<SIZE&&dis[Heap[now+1]]<dis[Heap[now]])now++;
 55         if(dis[Heap[root]]<=dis[Heap[now]])return;
 56         swap(Heap[root],Heap[now]);
 57         swap(pos[Heap[root]],pos[Heap[now]]);
 58         root=now;
 59     }
 60 }
 61 void dijkstra(int start)
 62 {
 63     int i,u,v;
 64     for(i=1;i<=N;i++)dis[i]=INF;dis[start]=0;
 65     for(i=1;i<=N;i++)Insert(i);
 66     while(SIZE>0)
 67     {
 68         u=Heap[1];Pop1(pos[u]);
 69         for(i=Head[u];i!=-1;i=edge[i].next)
 70         {
 71             v=edge[i].end;
 72             if(dis[v]>dis[u]+edge[i].value){dis[v]=dis[u]+edge[i].value;Push1(pos[v]);}
 73         }
 74     }
 75 }
 76 bool cmp1(node aa,node bb)
 77 {
 78     if(aa.x==bb.x)return aa.y<bb.y;
 79     return aa.x<bb.x;
 80 }
 81 bool cmp2(node aa,node bb)
 82 {
 83     if(aa.y==bb.y)return aa.x<bb.x;
 84     return aa.y<bb.y;
 85 }
 86 int main()
 87 {
 88     int n,m,i,k,k1,bx,by,ex,ey;
 89     n=read();m=read();
 90     memset(Head,-1,sizeof(Head));cnt=1;
 91     N=2*m+4;
 92     for(i=1;i<=m+2;i++)a[i].x=read(),a[i].y=read(),a[i].id=i;
 93     sort(a+1,a+m+3,cmp1);
 94     for(i=1;i<=m+1;i++)
 95     {
 96         if(a[i].x==a[i+1].x)addedge1(a[i].id,a[i+1].id,2*(a[i+1].y-a[i].y));
 97     }
 98     sort(a+1,a+m+3,cmp2);
 99     for(i=1;i<=m+1;i++)
100     {
101         if(a[i].y==a[i+1].y)addedge1(a[i].id+m+2,a[i+1].id+m+2,2*(a[i+1].x-a[i].x));
102     }
103     for(i=1;i<=m;i++)addedge1(i,i+m+2,1);
104     addedge1(m+1,m+1+m+2,0);addedge1(m+2,m+2+m+2,0);
105     dijkstra(m+1);
106     if(dis[m+2]!=INF)printf("%d",dis[m+2]);
107     else printf("-1");
108     /*不看n的范围的后果。。。写了个n^2的建图。。。
109     for(i=1;i<=m;i++)
110     {
111         x=read();y=read();
112         k=xy(x,y);
113         addedge1(k,n*n+k,1);
114     }
115     for(i=1;i<=n;i++)
116     {
117         for(j=1;j<=n;j++)
118         {
119             if(i<n){k=xy(i,j);k1=xy(i+1,j);addedge1(k,k1,2);addedge1(k+n*n,k1+n*n,2);}
120             if(j<n){k=xy(i,j);k1=xy(i,j+1);addedge1(k,k1,2);addedge1(k+n*n,k1+n*n,2);}
121         }
122     }
123     N=2*n*n;
124     bx=read();by=read();ex=read();ey=read();
125     addedge1(xy(bx,by),xy(bx,by)+n*n,0);
126     addedge1(xy(ex,ey),xy(ex,ey)+n*n,0);
127     dijkstra(xy(bx,by));
128     if(dis[xy(ex,ey)]!=INF)printf("%d",dis[xy(ex,ey)]);
129     else printf("-1");*/
130     fclose(stdin);
131     fclose(stdout);
132     return 0;
133 }

 

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