SUSTOJ_路痴的单身小涵(图中最短路的条数)

Posted bianjunting

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SUSTOJ_路痴的单身小涵(图中最短路的条数)相关的知识,希望对你有一定的参考价值。

  去年因为太low没有做出来校赛的最后一题,遂今年校赛做了这个题,下面我做详细描述。

原题链接

  本题大意:给定一个无向图G,每个边的权值为1,图中L表示起点,C表示终点,#表示未通路,给定时间k,让你判断是否能在给定时间k内走到C,并回答这样的路径有多少条?

  本题思路:裸的搜索问题,由于图过大,所以直接dfs搜会超时,需要先bfs求解答案如果k步内能走到则再进行下一步的求解。。。

参考代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <cmath>
#include <algorithm>
#define mid ((l + r) / 2)
using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef unsigned long long ull;
const double pi = acos(-1.0);

const int maxn = 1e3 + 5;
int n, m, k, step, ans, Dist;
char G[maxn][maxn];
int dist[maxn][maxn];
bool vis[maxn][maxn];
pii B, E, now, Next;

int bfs(int x, int y) 
    memset(vis, false, sizeof vis);
    memset(dist, 0, sizeof dist);
    queue <pii> Q;
    Q.push(make_pair(x, y));
    dist[x][y] = 0;
    while(!Q.empty()) 
        pii now = Q.front();
        Q.pop();
        if(now.first == E.first && now.second == E.second) return dist[now.first][now.second];
        for(int dx = -1; dx <= 1; dx ++) 
            for(int dy = -1; dy <= 1; dy ++) 
                if(abs(dx - dy) == 1) 
                    Next.first = now.first + dx;
                    Next.second = now.second + dy;
                    if(!vis[Next.first][Next.second] && Next.first >= 0 && Next.first < n && Next.second >= 0 && Next.second < m && G[Next.first][Next.second] != #) 
                        dist[Next.first][Next.second] = dist[now.first][now.second] + 1;
                        Q.push(make_pair(Next.first, Next.second));
                        vis[Next.first][Next.second] = true;
                    
                
            
        
    
    return -1;


void dfs(pii B, pii E, int D) 
    if(B.first == E.first && B.second == E.second) 
        if(D < Dist) 
            step = 1;
            Dist = D;
         else if(D == Dist) step ++;
        return;
    
    if(D > Dist) return;
    for(int i = -1; i <= 1; i ++) 
        for(int j = -1; j <= 1; j ++) 
            if(abs(i - j) == 1) 
                if(B.first + i >= 0 && B.first + i < n && B.second + j >= 0 && B.second + j < m) 
                    if(G[B.first + i][B.second + j] != # && !vis[B.first + i][B.second + j]) 
                        vis[B.first + i][B.second + j] = true;
                        dfs(make_pair(B.first + i, B.second + j), E, D + 1);
                        vis[B.first + i][B.second + j] = false;
                    
                
            
        
    


int main() 
    ios_base :: sync_with_stdio(false);
    int t, Case = 0;
    cin >> t;
    while(t --) 
        step = 0;
        Dist = 0x3f3f3f3f;
        cin >> n >> m >> k;
        for(int i = 0; i < n; i ++) cin >> G[i];
        for(int i = 0; i < n; i ++) 
            for(int j = 0; j < m; j ++) 
                if(G[i][j] == L) B = make_pair(i, j);
                if(G[i][j] == C) E = make_pair(i, j);
            
        
        ans = bfs(B.first, B.second);
        if(ans > k) ans = -1;
        cout << "Case #" << ++ Case << ": " << ans <<  ;
        if(ans != -1) 
            memset(vis, false, sizeof vis);
            dfs(B, E, 0);
            cout << step;
        
        cout << endl;
    
    return 0;

   相同的题目,如果边的权值不为1,则可用SPFA+dfs求解。

以上是关于SUSTOJ_路痴的单身小涵(图中最短路的条数)的主要内容,如果未能解决你的问题,请参考以下文章

POJ 3463 Sightseeing

POJ 3463 Sightseeing

HDU 1688

HDU 1688

最短路径条数(floyd)

浅入浅出数据结构(24)——最短路径问题