CF 173B Chamber of Secrets 最短路

题意:给定一个图,图中的#代表一个塔,图的右下角有一条蛇怪,向左边发射一条光线,光线经过被magic的塔能向四个方向发射,问经过最少多少次magic可以使每个从左上角进入的人都被石化。

思路:一开始思路很简单,直接用最简单的最短路,每次在四个方向上找到塔。然后push进队列,最后只要找到横坐标为1的塔即跳出。实现很简单,但是直接超时了,然后学长提供了一种很神的方法。

如果(x,y)是一个塔,那么代表节点i到j+n有一条路,j+n到i有一条路,然后问题就简化成找到节点1-n的最短路。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#include <iomanip>
#define PI acos(-1.0)
#define Max 1000005
#define inf 1<<28
#define LL(x) (x<<1)
#define RR(x)(x<<1|1)
using namespace std;

vector<int>g[Max];
int n,m;
int visit[Max];
int num[Max];
queue<int >q;
void bfs()
{
    int i,j;
    visit[n]=1;
    num[n]=0;
    q.push(n);
    while(!q.empty())
    {
        int tt=q.front();
        q.pop();
        for(i=0; i<g[tt].size(); i++)
        {
            int temp=g[tt][i];
            if(!visit[temp])
            {
                visit[temp]=1;
                q.push(temp);
                num[temp]=num[tt]+1;
            }
        }
    }
}
int main()
{
    int i,j,k,l;
    char x;
    cin>>n>>m;
    for(i=1; i<=n; i++)
    {
        for(j=1; j<=m; j++)
        {
            cin>>x;
            if(x=='#')
            {
                g[i].push_back(j+n);
                g[j+n].push_back(i);
            }
        }
    }
    bfs();
    if(num[1])
        cout<<num[1]<<endl;
    else
        cout<<-1<<endl;
    return 0;
}


你可能感兴趣的:(CF 173B Chamber of Secrets 最短路)