牛客网-2018年湘潭大学程序设计竞赛-F
题目链接:https://www.nowcoder.com/acm/contest/105/F
解题思路:这道题第一眼直接思路就是搜索,但想了半天没想到有什么好办法搜,然后就转成最短路写了,
因为多入口和出口,建立一个汇点一个源点,权值自己设,然后上下左右能相连的权值为1,传送阵(能用的前提下)入口和出口两个点的权值设为3;
然后就是最短路;
#include<iostream> #include<algorithm> #include<cstdio> #include<queue> #include<cstring> #define maxn 400005 #define inf 0x3f3f3f3f using namespace std; struct Edge { int next; int to; int w; }edge[maxn]; struct node { int num; int dist; node(int _num=0,int _dist=0):num(_num),dist(_dist){} friend bool operator<(node a,node b) { return a.dist>b.dist; } }; int head[maxn]; int cnt; int dist[maxn]; int visit[maxn]; int ans[maxn]; void add(int u,int v,int w) { edge[cnt].next=head[u]; edge[cnt].to=v; edge[cnt].w=w; head[u]=cnt++; } void dij(int u) { priority_queue<node>q; memset(dist,inf,sizeof(dist)); memset(visit,0,sizeof(visit)); dist[u]=0; q.push(node(u,0)); while(!q.empty()) { node p=q.top(); q.pop(); int now=p.num; for(int i=head[now];i!=-1;i=edge[i].next) { Edge e=edge[i]; if(dist[e.to]>dist[now]+e.w) { dist[e.to]=dist[now]+e.w; q.push(node(e.to,dist[e.to])); } } } } int main() { int n,m,q; int x,y,w; int tx,ty,ex,ey; int cot=0; char s[500][500]; while(cin>>n>>m>>q) { cot=cnt=0; memset(head,-1,sizeof(head)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>s[i][j]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(s[i][j]!='#') { if(s[i+1][j]!='#'&&i+1<=n) { x=(i-1)*m+j;y=(i)*m+j;add(x,y,1); } if(s[i-1][j]!='#'&&i-1>=1) { x=(i-1)*m+j;y=(i-2)*m+j;add(x,y,1); } if(s[i][j+1]!='#'&&(j+1)<=m) { x=(i-1)*m+j;y=(i-1)*m+j+1;add(x,y,1); } if(s[i][j-1]!='#'&&(j-1)>=1) { x=(i-1)*m+j;y=(i-1)*m+j-1;add(x,y,1); } } if(s[i][j]=='S') { x=0;y=(i-1)*m+j;add(x,y,1); } if(s[i][j]=='T') { ans[++cot]=(i-1)*m+j; } } while(q--) { cin>>tx>>ty>>ex>>ey; tx++;ty++;ex++;ey++; if(s[tx][ty]!='#'&&s[ex][ey]!='#') { x=(tx-1)*m+ty;y=(ex-1)*m+ey; add(x,y,3); } } dij(0); int a=inf; for(int i=1;i<=cot;i++) { a=min(a,dist[ans[i]]); } if(a==inf) cout<<"-1\n"; else cout<<a-1<<endl; } }