Find a Way


這道題,是一個典型最短路徑問題,用寬搜,但不要理解爲雙起點,而要理解爲雙寬搜。這道題有多個終點,我們不要一個一個點地枚舉,這樣做會超時(我試過的,而且還卡了很久不知道爲什麼錯.而是算沒個人到每個KFC的距離,再用兩人的距離和比較,取最小的。

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
long long n,b[40001][3]={0},s=0,d[201][201]={0},d1[201][201],m,direction[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
char a[201][201];
queue<int>p;
queue<int>p1;
void search(int i2,int j2){
memset(d,0x3f3f3f3f,sizeof(d));
	d[i2][j2]=0;
	while(p.size()){
		p.pop();p1.pop();
	}
	p.push(i2);p1.push(j2);
	while(p.size()){
	    int sx=p.front();p.pop();
		int sy=p1.front();  p1.pop();
	        for(int i=0;i<4;i++){
	        	int x1=sx+direction[i][0],x2=sy+direction[i][1];
	        	if(x1>=1&&x1<=n&&x2>=1&&x2<=m&&d[x1][x2]>d[sx][sy]+1&&a[x1][x2]!='#'){//沒超出邊界且沒遇到牆才行(不要重複走)
	        		p.push(x1);p1.push(x2);
	        		d[x1][x2]=d[sx][sy]+1;
				} 
			}		  
	}
}
void search1(int i2,int j2){
memset(d1,0x3f3f3f3f,sizeof(d1));
	d1[i2][j2]=0;
	while(p.size()){
		p.pop();p1.pop();
	}
	p.push(i2);p1.push(j2);
	while(p.size()){
	    int sx=p.front();p.pop();
		int sy=p1.front();  p1.pop();
	        for(int i=0;i<4;i++){
	        	int x1=sx+direction[i][0],x2=sy+direction[i][1];
	        	if(x1>=1&&x1<=n&&x2>=1&&x2<=m&&d1[x1][x2]>d1[sx][sy]+1&&a[x1][x2]!='#'){
	        		p.push(x1);p1.push(x2);
	        		d1[x1][x2]=d1[sx][sy]+1;
				} 
			}		
		}  
	}

int main(){
	while(cin>>n>>m){
		long long s=0,stx1,sty1,stx2,sty2,ans=100000000;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				cin>>a[i][j];
				if(a[i][j]=='Y'){
					stx1=i;sty1=j;
				}
				else if(a[i][j]=='M'){
					stx2=i;sty2=j;
				}
				else if(a[i][j]=='@'){
					b[++s][1]=i;b[s][2]=j;//存終點
				}
			}
		}
search(stx1,sty1);search1(stx2,sty2);
for(int i=1;i<=s;i++){
	long long time=d[b[i][1]][b[i][2]]+d1[b[i][1]][b[i][2]];//距離和
	ans=min(time,ans);
}
cout<<ans*11<<endl;//記得乘以一個11哦!
} 
}


發佈了29 篇原創文章 · 獲贊 12 · 訪問量 4264
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章