CodeforcesD. Aztec Catacombs

$n \leq 300000$的完全无向图，每条边有可行和不可行的状态，一开始只有$m \leq 300000$条边是可行的，给出。每次从$x$走到$y$时，所有与$x$相连的边的可行/不可行状态会改变。问从1最少走几步到$n$。

 1 //#include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 //#include<math.h>
5 //#include<set>
6 //#include<queue>
7 //#include<vector>
8 #include<algorithm>
9 #include<stdlib.h>
10 using namespace std;
11
12 #define LL long long
14 {
15     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
16     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
17 }
18
19 //Pay attention to '-' , LL and double of qread!!!!
20
21 int n,m;
22 #define maxn 300011
23 struct Edge{int to,next;}edge[maxn<<1]; int first[maxn],le=2;
24 void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;}
25 void insert(int x,int y) {in(x,y); in(y,x);}
26
28 int find(int x) {return x==ufs[x]?x:(ufs[x]=find(ufs[x]));}
29 void Union(int x,int y) {if ((x=find(x))!=(y=find(y))) ufs[x]=y,size[y]+=size[x];}
30 void bfs(int s)
31 {
32     for (int i=1;i<=n;i++) dis[i]=0x3f3f3f3f,pre[i]=0;
35     {
37         for (int i=first[x];i;i=edge[i].next)
38         {
39             Edge &e=edge[i]; if (e.to==1) continue;
40             if (dis[e.to]==0x3f3f3f3f)
41             {
42                 dis[e.to]=dis[x]+1;
43                 pre[e.to]=x;
44                 que[tail++]=e.to;
45             }
46         }
47     }
48 }
49
50 int main()
51 {
54     bfs(1);
55     if (dis[n]<=4)
56     {
57         printf("%d\n1 ",dis[n]);
58         int ans[10],lans=0;
59         for (int i=n;i!=1;i=pre[i]) ans[++lans]=i;
60         for (int i=lans;i;i--) printf("%d ",ans[i]);
61         return 0;
62     }
63     for (int i=1;i<=n;i++) if (dis[i]==2)
64     {
65         printf("4\n1 %d %d 1 %d",pre[i],i,n);
66         return 0;
67     }
68     for (int i=2;i<n;i++) du[i]=-1,ufs[i]=i,size[i]=1;
69     for (int i=2;i<n;i++) if (dis[i]==1)
70         for (int j=first[i];j;j=edge[j].next)
71         {
72             if (edge[j].to!=1) Union(i,edge[j].to);
73             du[i]++;
74         }
75     for (int i=2;i<n;i++) if (dis[i]==1)
76     {
77         int u=size[find(i)];
78         if (u-1==du[i]) continue;
79         bfs(i);
80         for (int j=2;j<n;j++) if (dis[j]==2)
81         {
82             printf("5\n1 %d %d %d %d %d",i,pre[j],j,i,n);
83             return 0;
84         }
85     }
86     puts("-1");
87     return 0;
88 }
View Code

posted @ 2018-06-16 18:57  Blue233333  阅读(294)  评论(0编辑  收藏  举报