【ZSTU4215 2015年12月浙理工校赛 F】【Dijkstra最短路】Landlocked 到达海洋最少跨越国家数

4215: Landlocked

Time Limit: 5 Sec   Memory Limit: 128 MB
Submit: 298   Solved: 41

Description

Canada is not a landlocked country: the country touches at least one ocean (in fact, it touches three).

There are 46 countries (including Bolivia and Mongolia, for example) which are landlocked. That is, they do not touch an ocean, but by going through one other country, an ocean can be reached. For example, a person in Mongolia can get to an ocean by passing through Russia.

Liechtenstein and Uzbekistan are the only two countries in the world which are land-landlocked. That is, not only are they land-locked, but all countries which surround these two countries are land-locked countries. Thus, one would have to pass through at least two different countries when leaving Uzbekistan before arriving at an ocean.

Your task is to determine how landlocked each country is on a given map. We say that a country is not landlocked (recorded as 0) if it touches water in any adjacent cell in either a horizontal, vertical, or diagonal direction. If a country is landlocked, you must calculate the minimum number of borders that one must cross in order to travel from the country to water. Each step of such a journey must be to a cell that is adjacent in either a horizontal, vertical, or diagonal direction. Crossing a border is defined as taking a step from a cell in one country to an adjacent cell in a different country.

Note that countries may not be connected to themselves (as in a country formed of islands). In this case, the landlocked value for the country is the minimal of each connected region of the country.

Input

The first line contains N and M (1 ≤ N, M ≤ 1000).

On each of the next N lines, there are M capital letters. Each country will be represented by a unique letter, with the exception that the letter W is reserved to indicate the water in the oceans or seas that will be used to determine the how landlocked each country is.

Output

The output consists of the country letter followed by a space, followed by the landlockedness for that particular country. Output should be in alphabetical order

Sample Input

7 10 
WWWWWCCDEW
WWWWCCEEEW
WTWWWCCCCW
WWFFFFFFWW
WWFAAAAFWW
WWFABCAFFW
WWFAAAAFWW

Sample Output

A 1
B 2
C 0
D 1
E 0
F 0
T 0


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;}
template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;}
const int N=1010,M=3e6,Z=1e9+7,ms63=0x3f3f3f3f;
int casenum,casei;
int n,m;
char a[N][N];
int f[N][N];
bool e[N][N];
int ans[128];
const int dy[8]={-1,-1,-1,0,0,1,1,1};
const int dx[8]={-1,0,1,-1,1,-1,0,1};
struct node
{
    int y,x,v;
    node(){}
    node(int y_,int x_,int v_){y=y_;x=x_;v=v_;}
    bool operator < (const node &b)const
    {
        return v>b.v;
    }
};
priority_queue<node>q;
void inq(int y,int x,int v)
{
    if(v>=f[y][x])return;
    f[y][x]=v;
    gmin(ans[a[y][x]],v);
    q.push(node(y,x,v));
}
void dijkstra()
{
    MS(f,63);
    MS(ans,63);
    MS(e,0);
    while(!q.empty())
    {
        int y=q.top().y;
        int x=q.top().x;
        int v=q.top().v;
        q.pop();
        if(e[y][x])continue;e[y][x]=1;
        for(int i=0;i<8;++i)
        {
            int yy=y+dy[i];
            int xx=x+dx[i];
            if(yy<1||yy>n||xx<1||xx>m)continue;
            if(a[yy][xx]==a[y][x])inq(yy,xx,v);
            else inq(yy,xx,v+1);
        }
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=n;++i)scanf("%s",a[i]+1);
        for(int i=1;i<=n;++i)
        {
            for(int j=1;j<=m;++j)
            {
                if(a[i][j]=='W')inq(i,j,-1);
            }
        }
        dijkstra();
        ans['W']=ms63;
        for(char i='A';i<='Z';++i)if(ans[i]!=ms63)
        {
            printf("%c %d\n",i,ans[i]);
        }
    }
    return 0;
}
/*
【trick&&吐槽】
这题十分水。用spfa RE了,改成dijkstra就AC掉啦。

【题意】
给你一个n*m(1000*1000)的地图。
地图上只存在大写字符。其中,'W'代表海洋,其他字符分别代表一个国家。
问你,每个国家,想要到达海洋,至少要经过多少国家?
一个国家可能是多个联通块,输出其所有土地经过国家数的最小值即可~

【类型】
最短路 dijkstra+heap

【分析】
初始把海洋入队,最短路权值设为-1,然后展开dijkstra。
如果是同一国家,那么最短路权值不变;如果是不同国家,最短路权值+1.
最后输出答案即可。

唯一需要注意的是——
我们要更新出,到达每个点的最短路,而不能只保留对于一个国家的最短路。

【时间复杂度&&优化】
O(nm log(nm))

*/


你可能感兴趣的:(图论-最短路)