这道题似乎还没有最短路的题解,这里给出一种 d i j k s t r a dijkstra dijkstra的做法(其实是最近学图论学疯了,什么都想用图论来做)
题目大意:
给出一个图,查询这个图的:
连通块的个数、
最大连通块的大小、
合并相邻连通块后最大的连通块(以及这个可以调死你的拆墙的方向)
分析:
首先看到数据范围: 1 ≤ n , m ≤ 50 1≤n,m≤50 1≤n,m≤50
我们给每个点一个编号,让其与相邻4个点连边;(注意这里是连单向边,因为题目给出的每个点都描述了自己周围墙的状态,所以只用连自己的那条就行了)
建图代码:
int pos[N];
int cnt,head[N];
struct edge{
int to,nxt;}e[N<<1];
inline void addedge(int x,int i,int j){
if(!(x&1)) add(m*(i-1)+j,m*(i-1)+j-1);//西
if(!(x&(1<<1))) add(m*(i-1)+j,m*(i-2)+j);//北
if(!(x&(1<<2))) add(m*(i-1)+j,m*(i-1)+j+1);//东
if(!(x&(1<<3))) add(m*(i-1)+j,m*i+j);//南
}
main(void){
m=read();n=read();num=n*m;
for(int tmp,i=1;i<=n;i++)
for(int j=1;j<=m;j++){
tmp=m*(i-1)+j;
addedge((pos[tmp]=read()),i,j);
}
}
建完图后考虑怎么统计连通块的数量
遍历所有点,如果该点没有被访问过,那么就可以新开一个连通块,数量++;
memset(dis,0x3f,sizeof(dis));
for(int i=1;i<=num;i++)
if(!vis[i]) ++room,siz[++tot]=dijkstra(i);
至于连通块的大小,可以在 d i j k s t r a dijkstra dijkstra里面统计:
int dis[N][N]
bool vis[N];
priority_queue<pair