【ZCMU1895】Landlocked(最短路)

来源:互联网 发布:莫比乌斯环戒指知乎 编辑:程序博客网 时间:2024/05/19 16:49

记录一个菜逼的成长。。

题目链接

题目大意:
给你n*m的矩阵
‘W’表示水,其他表示国家
问这些国家最少需要走多少步,才能到达边界与水相邻的国家

国家这么多,水就一种,我们不妨反着求。
求从水到这些国家的最短路
这里就有两种算法
一种就是spfa算法
测试了无优化,SLF优化,SLF+LLL优化
实际上这里还是SLF优化快

#include <bits/stdc++.h>using namespace std;#define ALL(v) (v).begin(),(v).end()#define cl(a,b) memset(a,b,sizeof(a))#define clr clear()#define pb push_back#define mp make_pair#define fi first#define se secondtypedef long long LL;typedef pair<int,int> PII;const int INF = 0x3f3f3f3f;const int maxn = 1000 + 10;char str[maxn][maxn];int vis[maxn][maxn],dis[maxn][maxn],n,m;int ans[30];int dx[] = {-1,-1,0,1,1,1,0,-1},dy[] = {0,1,1,1,0,-1,-1,-1};deque<PII>q;void spfa(){    while(!q.empty()){        PII f = q.front();q.pop_front();        vis[f.fi][f.se] = 0;        for( int i = 0; i < 8; i++ ){            int nx = f.fi + dx[i],ny = f.se + dy[i];            if(nx < 1 || nx > n || ny < 1 || ny > m)continue;            int w = (str[nx][ny] != str[f.fi][f.se]);            if(dis[nx][ny] > dis[f.fi][f.se] + w){                dis[nx][ny] = dis[f.fi][f.se] + w;                if(!vis[nx][ny]){                    vis[nx][ny] = 1;                    ///SLF优化                    if(dis[nx][ny] < dis[q.front().fi][q.front().se]){                        q.push_front(mp(nx,ny));                    }                    else {                        q.push_back(mp(nx,ny));                    }                }            }        }    }}void init(){    cl(dis,INF);    cl(vis,0);    cl(ans,INF);}int main(){    while(~scanf("%d%d",&n,&m)){        init();        for( int i = 1; i <= n; i++ ){            scanf("%s",str[i]+1);            for( int j = 1; j <= m; j++ ){                if(str[i][j] == 'W'){                    if(!vis[i][j]){                        vis[i][j] = 1;                        dis[i][j] = 0;                        q.push_back(mp(i,j));                    }                }            }        }        spfa();        for( int i = 1; i <= n; i++ ){            for( int j = 1; j <= m; j++ ){                if(str[i][j] != 'W'){                    ans[str[i][j]-'A'] = min(ans[str[i][j]-'A'] , dis[i][j]);                }            }        }        for( int i = 0; i < 26; i++ ){            if(ans[i] != INF){                printf("%c %d\n",i+'A',ans[i]-1);            }        }    }    return 0;}

另一种是堆优化的dijkstra算法
优先队列的比较结构定义

/// One of the @link comparison_functors comparison functors@endlink.  template<typename _Tp>    struct greater : public binary_function<_Tp, _Tp, bool>    {      bool operator()(const _Tp& __x, const _Tp& __y) const      { return __x > __y; }    }; /// One of the @link comparison_functors comparison functors@endlink.  template<typename _Tp>    struct less : public binary_function<_Tp, _Tp, bool>    {      bool operator()(const _Tp& __x, const _Tp& __y) const      { return __x < __y; }    };
#include <bits/stdc++.h>using namespace std;#define ALL(v) (v).begin(),(v).end()#define cl(a,b) memset(a,b,sizeof(a))#define clr clear()#define pb push_back#define mp make_pair#define fi first#define se secondtypedef long long LL;typedef pair<int,int> PII;const int INF = 0x3f3f3f3f;const int maxn = 1000 + 10;char str[maxn][maxn];int vis[maxn][maxn],dis[maxn][maxn],n,m;int ans[30];int dx[] = {-1,-1,0,1,1,1,0,-1},dy[] = {0,1,1,1,0,-1,-1,-1};struct Node{    int dis,x,y;    Node(){}    Node(int d,int xx,int yy):dis(d),x(xx),y(yy){}    //小顶堆    friend bool operator > (const Node& a,const Node& b){        return a.dis > b.dis;     }     //大顶堆    friend bool operator < (const Node& a,const Node& b){        return a.dis < b.dis;     } };struct cmp{    bool operator()(const Node &a,const Node &b)const{        return a.dis > b.dis;//小顶堆,, 改成<是大顶堆     }};//优先队列这里有两种定义优先级的方法priority_queue<Node,vector<Node>,greater<Node> >q;//如果是重载运算符就用这种形式//priority_queue<Node,vector<Node>,cmp>q;//如果是定义结构,用这种形式void dijkstra(){    while(!q.empty()){        Node f = q.top();q.pop();        vis[f.x][f.y] = 0;        for( int i = 0; i < 8; i++ ){            int nx = f.x + dx[i],ny = f.y + dy[i];            if(nx < 1 || nx > n || ny < 1 || ny > m)continue;            int w = (str[nx][ny] != str[f.x][f.y]);            if(dis[nx][ny] > dis[f.x][f.y] + w){                dis[nx][ny] = dis[f.x][f.y] + w;                if(!vis[nx][ny]){                    vis[nx][ny] = 1;                    q.push(Node(dis[nx][ny],nx,ny));                }            }        }    }}void init(){    cl(dis,INF);    cl(vis,0);    cl(ans,INF);}int main(){    while(~scanf("%d%d",&n,&m)){        init();        for( int i = 1; i <= n; i++ ){            scanf("%s",str[i]+1);            for( int j = 1; j <= m; j++ ){                if(str[i][j] == 'W'){                    if(!vis[i][j]){                        vis[i][j] = 1;                        dis[i][j] = 0;                        q.push(Node(0,i,j));                    }                }            }        }        dijkstra();        for( int i = 1; i <= n; i++ ){            for( int j = 1; j <= m; j++ ){                if(str[i][j] != 'W'){                    ans[str[i][j]-'A'] = min(ans[str[i][j]-'A'] , dis[i][j]);                }            }        }        for( int i = 0; i < 26; i++ ){            if(ans[i] != INF){                printf("%c %d\n",i+'A',ans[i]-1);            }        }    }    return 0;}
0 0
原创粉丝点击