[BZOJ2834]回家的路

Description

Input

Output

Sample Input

2 1
1 2
1 1 2 2

Sample Output

5
 
思路还是很简单的,然而最短路打错各种对拍各种调了一早上
代码:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 #include<queue>
 6 #include<cstdlib>
 7 #include<map>
 8 #include<algorithm>
 9 #define M 300010
10 using namespace std;
11 vector<int>S1[M],S2[M];
12 map<int,int>f[M];
13 int n,m,num,cnt,x1,x2,y1,y2;
14 int head[M],dis[M],vis[M],st[M],v[M];
15 struct point{int to,next,dis;}e[M<<1];
16 void add(int from,int to,int dis) {
17     e[++num].next=head[from];
18     e[num].to=to;
19     e[num].dis=dis;
20     head[from]=num;
21 }
22 void SPFA(int s) {
23     memset(dis,63,sizeof(dis));
24     queue<int>Q;dis[s]=0;
25     Q.push(s);
26     while(!Q.empty()) {
27         int x=Q.front();Q.pop();vis[x]=false;
28         for(int i=head[x];i;i=e[i].next) {
29             int to=e[i].to;
30             if(dis[x]+e[i].dis<dis[to]) {
31                 dis[to]=dis[x]+e[i].dis;
32                 if(!vis[to]) vis[to]=true,Q.push(to);
33             }
34         }
35     }
36 }
37 int get(int x,int y) {
38     return 2*abs(v[st[x]]-v[st[y]]);
39 }
40 bool cmp(int x,int y) {
41     return v[x]<v[y];
42 }
43 int main() {
44     scanf("%d%d",&n,&m);
45     for(int i=1;i<=m;i++) {
46         int x,y;scanf("%d%d",&x,&y);
47         if(f[x][y]!=0) continue;
48         f[x][y]=++cnt;
49         S1[x].push_back(cnt);v[cnt]=y;
50         S2[y].push_back(++cnt);v[cnt]=x;
51         add(cnt-1,cnt,1),add(cnt,cnt-1,1);
52     }
53     scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
54     if(!f[x1][y1]) {
55         f[x1][y1]=++cnt;
56         S1[x1].push_back(cnt);v[cnt]=y1;
57         S2[y1].push_back(++cnt);v[cnt]=x1;
58         add(cnt-1,cnt,0),add(cnt,cnt-1,0);
59     }
60     else {
61         int t=f[x1][y1];
62         add(t+1,t,0),add(t,t+1,0);
63     }
64     if(!f[x2][y2]) {
65         f[x2][y2]=++cnt;
66         S1[x2].push_back(cnt);v[cnt]=y2;
67         S2[y2].push_back(++cnt);v[cnt]=x2;
68         add(cnt-1,cnt,0),add(cnt,cnt-1,0);
69     }
70     else {
71         int t=f[x2][y2];
72         add(t+1,t,0),add(t,t+1,0);
73     }
74     for(int i=1;i<=(n<<1);i++) {
75         int tmp=0;
76         for(int j=0;j<S1[i].size();j++) st[++tmp]=S1[i][j];
77         if(tmp>1) {
78             sort(st+1,st+tmp+1,cmp);
79             for(int j=2;j<=tmp;j++) {
80                 add(st[j-1],st[j],get(j-1,j));
81                 add(st[j],st[j-1],get(j,j-1));
82             }
83         }
84         tmp=0;
85         for(int j=0;j<S2[i].size();j++) st[++tmp]=S2[i][j];
86         if(tmp>1) {
87             sort(st+1,st+tmp+1,cmp);
88             for(int j=2;j<=tmp;j++) {
89                 add(st[j-1],st[j],get(j-1,j));
90                 add(st[j],st[j-1],get(j,j-1));
91             }
92         }
93     }
94     int s=f[x1][y1],t=f[x2][y2];
95     SPFA(s);
96     printf("%d\n",dis[t]>1e8?-1:dis[t]);
97     return 0;
98 }

 

HINT

N<=20000,M<=100000

posted @ 2018-12-06 09:49  Slr  阅读(160)  评论(0编辑  收藏  举报