P1457 [USACO2.1]城堡 The Castle题解

博客介绍了使用Dijkstra算法解决USACO2.1题目《城堡》的方法,包括如何构建图、计算连通块数量和大小,以及如何优化求解合并相邻连通块后的最大连通块。文章特别讨论了避免重新运行Dijkstra的优化策略,并提到了判断最佳推墙方向的规则。
摘要由CSDN通过智能技术生成

这道题似乎还没有最短路的题解,这里给出一种 d i j k s t r a dijkstra dijkstra的做法(其实是最近学图论学疯了,什么都想用图论来做

题目大意:

给出一个图,查询这个图的:

连通块的个数、

最大连通块的大小、

合并相邻连通块后最大的连通块(以及这个可以调死你的拆墙的方向

分析:

首先看到数据范围: 1 ≤ n , m ≤ 50 1≤n,m≤50 1n,m50

我们给每个点一个编号,让其与相邻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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值