【题解】P2243 电路维修 双端队列搜索

建边,不转就能联通的建0,需要转才能联通的建1

在一张边权只有0/1的图上,可以用双端队列bfs

0边从队头入队,1边从队尾入队

code

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 namespace gengyf{
 4     #define ll long long
 5     #define mp make_pair
 6     #define fir first
 7     #define sec second
 8     const int maxn=510;
 9     inline int read(){
10         int x=0,f=1;char s=getchar();
11         while(s<'0'||s<'9'){if(s=='-')f=-1;s=getchar();}
12         while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
13         return f*x;
14     }
15     deque<pair<int,int> > q; 
16     vector<pair<pair<int,int>,int> > p[maxn][maxn];
17     int T,n,m,dis[maxn][maxn],vis[maxn][maxn]; 
18     char a[maxn][maxn];
19     inline void add(int a,int b,int x,int y,int z){
20         p[a][b].push_back(mp(mp(x,y),z)); 
21     } 
22     int main(){
23         scanf("%d",&T);
24         while(T--){
25             scanf("%d%d",&n,&m);
26             for(int i=1;i<=n;i++){
27                 scanf("%s",a[i]+1);
28             }
29             for(int i=0;i<=n;i++)
30                 for(int j=0;j<=m;j++){
31                     p[i][j].clear();
32                 }
33             for(int i=1;i<=n;i++)
34                 for(int j=1;j<=m;j++){
35                     if(a[i][j]=='/'){
36                         add(i-1,j-1,i,j,1);
37                         add(i,j,i-1,j-1,1);
38                         add(i,j-1,i-1,j,0);
39                         add(i-1,j,i,j-1,0);
40                     }
41                     else {
42                         add(i-1,j-1,i,j,0);
43                         add(i,j,i-1,j-1,0);
44                         add(i,j-1,i-1,j,1);
45                         add(i-1,j,i,j-1,1);
46                     }
47                 }
48             memset(dis,0x3f,sizeof(dis));
49             dis[0][0]=0;
50             memset(vis,0,sizeof(vis));
51             q.clear();
52             q.push_back(mp(0,0));
53             while(!q.empty()){
54                 int x=q.front().fir,y=q.front().sec;
55                 q.pop_front();
56                 vis[x][y]=1;
57                 if(x==n&&y==m){
58                     printf("%d\n",dis[x][y]);
59                     goto end;
60                 } 
61                 for(int i=0;i<p[x][y].size();i++){
62                     int xx=p[x][y][i].fir.fir;
63                     int yy=p[x][y][i].fir.sec;
64                     int z=p[x][y][i].sec;
65                     if(vis[xx][yy])continue;
66                     if(dis[xx][yy]>dis[x][y]+z){
67                         dis[xx][yy]=dis[x][y]+z;
68                         if(z){
69                             q.push_back(mp(xx,yy)); 
70                         }
71                         else {
72                             q.push_front(mp(xx,yy));
73                         }
74                     }
75                 }
76             }
77             puts("NO SOLUTION");
78             end:;
79         }
80         return 0;
81     }
82 }
83 signed main(){
84     gengyf::main();
85     return 0;
86 }
View Code

 

posted @ 2019-10-21 16:31  喵の耳  阅读(240)  评论(1编辑  收藏  举报