圖的搜索和最短路徑-Saving James Bond

圖的搜索-深度優先搜索DFS

  • 題目
    06-圖2 Saving James Bond - Easy Version
  • 分析
    James從中心島嶼開始跳,這一跳需要進行特殊處理,然後在鱷魚頭上跳的時候,利用dfs進行搜索,一旦可以跳到安全區域就結束搜索。
    注意中心島嶼並不是P[0]。
  • 代碼
#include<stdio.h>
#include<math.h>

#define maxn 101

int N,D;
int visited[maxn];
int flag;

struct point{
    int x;
    int y;
}P[maxn];

//求某個點與原點的距離的平方
double distance1(int i)
{
    return P[i].x * P[i].x + P[i].y * P[i].y;
}
//求某兩個點之間的距離的平方
double distance2(i, j)
{
    return ((P[i].x-P[j].x)*(P[i].x-P[j].x) + (P[i].y-P[j].y)*(P[i].y-P[j].y));
}

int canSave(int i)
{
    if(P[i].x-D <= -50 || P[i].x+D >= 50 || P[i].y-D <= -50 || P[i].y+D >= 50)
        return 1;
    return 0;
}

void dfs(int i){
    //printf("%d\n",i);
    visited[i] = 1;
    if(canSave(i)){
        flag = 1;
        return;
    }else{
        int j;
        for(j=0; j<N; j++){
            if(!visited[j] && distance2(i,j)<=D*D){
                dfs(j);
            }
            if(flag)    break; 
        }
    }   
}

int main()
{
    flag = 0;
    #ifndef ONLINE_JUDGE
    freopen("save1.txt","r",stdin);
    #endif

    int i;
    scanf("%d%d", &N,&D);
    for(i=0; i<N; i++){
        scanf("%d%d", &P[i].x, &P[i].y);
        visited[i] = 0;
    }

    if(7.5+D >= 50) flag = 1;

    if(!flag){
        for(i=0; i<N; i++){
            if(!visited[i] && (7.5+D)*(7.5+D)>=distance1(i)){
                dfs(i);
            }
            if(flag)    break;      
        }
    }

    if(flag){
        printf("Yes\n");
    }else{
        printf("No\n");
    }

    return 0;
}

圖的最短路徑

  • 題目
    07-圖5 Saving James Bond - Hard Version (30分)
  • 分析
    這道題是求一個單源無向無權重的圖的最短路徑問題,但不是普通意義上的最短路徑,一般的最短路徑是求一個頂點到其餘各個頂點的最短路徑,而這道題是求從中心點到跳出邊緣的最短路徑。
    需要注意的是:一是求最少跳數的最短路(bfs搜索,同時記錄跳數)。二是要保存最短路徑(用一個path[]數組來保存),三是當跳數相同時,最短路選擇第一跳最短的那個路徑(可以先根據第一跳的長度來排序)。
    上面這樣做的話,其實找到的第一個可以跳出去的點,它的深度就是最短的跳數,此時就可以輸出了。因爲本身就是按照廣度優先算法,第一個滿足的點就是深度最小的。
  • 我的代碼
#include<iostream>
#include<algorithm>
#include<stack> 
#include<queue>
using namespace std;
#define maxn 101


int N,D;
int dist[maxn];//P[0]表示原點,dist[i]表示P[i]到原點的最短距離 
int path[maxn];//path[i]表示到P[0]的路上經過的頂點 
int flag;
int minPath = maxn;
queue<int> Q;
stack<int> S;

struct point{
    int x;
    int y;
}P[maxn];

double distance1(int i)
{
    return P[i].x * P[i].x + P[i].y * P[i].y;
}
double distance2(int i,int j)
{
    return ((P[i].x-P[j].x)*(P[i].x-P[j].x) + (P[i].y-P[j].y)*(P[i].y-P[j].y));
}

int canSave(int i)
{
    if(P[i].x-D <= -50 || P[i].x+D >= 50 || P[i].y-D <= -50 || P[i].y+D >= 50)
        return 1;
    return 0;
}

int comp(const point &a, const point &b)
{
    if( (a.x * a.x + a.y * a.y) < (b.x * b.x + b.y * b.y))  return 1;
    return 0;
}

int BFS()
{
    int tmpPath = 1,i;
    for(i=1; i<=N; i++){
        if(dist[i]==-1 && (7.5+D)*(7.5+D)>=distance1(i)){
            Q.push(i);
            dist[i] = 2;
            //printf("%d\n", i);
        }   
    }
    while(!Q.empty()){
        int tmp = Q.front();
        Q.pop();

        if(canSave(tmp)){
            flag = 1;
            minPath = dist[tmp];
            int k;
            for(k=0; k<minPath-1; k++){
                S.push(tmp);
                tmp = path[tmp];
            }
            break;
        }

        for(i=1; i<=N; i++){
            if(dist[i]==-1 && distance2(tmp,i)<=D*D ){
                dist[i] = dist[tmp] + 1;
                path[i] = tmp;
                Q.push(i);
            }
        }
    }
}
int main()
{
    flag = 0;
    #ifndef ONLINE_JUDGE
    freopen("save2.txt","r",stdin);
    #endif


    int i;
    scanf("%d%d", &N,&D);
    for(i=1; i<=N; i++){
        scanf("%d%d", &P[i].x, &P[i].y);
        //visited[i] = 0;
    }
    sort(P+1, P+N+1, comp); //排序 
    for(i=1; i<=N; i++){
        dist[i] = -1;
        path[i] = -1;
    }

    if(7.5+D >= 50){
        printf("1\n");
        return 0;
    }

    BFS();

    if(flag){
        printf("%d\n",minPath);
        for(i=0; i<minPath-1; i++){
            int tmp;
            tmp = S.top();
            S.pop();
            printf("%d %d\n", P[tmp].x, P[tmp].y);
        }
    }else{
        printf("0\n");
    }

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