• ACM经典问题--布线问题(三)


    1. 问题描述

    印刷电路板将布线区域划分成 n×m 个方格阵列,要求确定连接方格阵列中的方格a 点到方格b 的最短布线方案。在布线时,电路只能沿直线布线,为了避免线路相交,已布了线的方格做了封锁标记,其他线路不允许穿过被封锁的方格。问线路至少穿过几个方格。

    输入格式

    输入的第一行是两个整数 n 和m(2<=n<=100,2<=m<=100),表示阵列的范围,以及被封锁的方格。接下来有k 行,每行两个整数x 和y。表示被封锁的方格(1<=x<=n,1<=y<=m)。再接下来是四个整数x1 , y1 , x2 , y2 表示起点a 的坐标和起点b 的坐标。

    输出格式

    输出最短的布线方案的长度,若不存在,则输出-1。

    输入样例

    7 7 14
    1 3
    2 3
    2 4
    3 5
    4 4
    4 5
    5 1
    5 5
    6 1
    6 2
    6 3
    7 1
    7 2
    7 3
    3 2 4 6
    输出样例
    10

    2. 题目分析

    用队列式分支限界法来考虑布线问题。布线问题的解空间是一个图,则从起始位置 a开始将它作为第一个扩展结点。与该扩展结点相邻并可达的方格成为可行结点被加入到活结
    点队列中,并且将这些方格标记为1,即从起始方格a 到这些方格的距离为1。接着,从活结点队列中取出队首结点作为下一个扩展结点,并将与当前扩展结点相邻且未标记过的方格标记为2,并存入活结点队列。这个过程一直继续到算法搜索到目标方格b 或活结点队列为空时为止。

    3. 问题实现

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<queue>
    using namespace std ;
    struct Point { //表示方格
    	int x , y , step ;
    } ;
    queue<Point> Q ; //用以存放扩展节点的队列
    int vis[111][111] ;
    int dir[4][2] = { 0 , 1 , 1 , 0 , 0 , -1 , -1 , 0 } ;
    int n , m , k , X1 , Y1 , x2 , y2 ;
    int solve () {
    	Point u , v ;
    	int i ;
    	while ( !Q.empty () ) {
    		u = Q.front () , Q.pop () ; //将队列中的首元素取出用以扩展
    		if ( u.x == x2 && u.y == y2 ) return u.step ; //已经是终点了
    		for ( i = 0 ; i < 4 ; i ++ ) { //朝着4 个方向进行扩展
    			int xx = u.x + dir[i][0] ;
    			int yy = u.y + dir[i][1] ;
    			if ( xx <= 0 || xx > n || yy <= 0 || yy > m ) continue ;
    			if ( vis[xx][yy] ) continue ;
    			v.step = u.step + 1 ;
    			v.x = xx , v.y = yy ;
    			vis[xx][yy] = 1 ;
    			Q.push ( v ) ;
    		}
    	}
    	return -1 ;
    }
    int main () {
    	int x , y ;
    	while ( scanf ( "%d%d%d" , &n , &m , &k ) != EOF ) {
    			memset ( vis , 0 , sizeof ( vis ) ) ;
    		while ( !Q.empty () ) Q.pop () ;
    		while ( k -- ) {
    			scanf ( "%d%d" , &x , &y ) ;
    			vis[x][y] = 1 ;
    		}
    		scanf ( "%d%d%d%d" , &X1 , &Y1 , &x2 , &y2 ) ;
    		Point u ;
    		u.x = X1 , u.y = Y1 , u.step =1 ;
    		Q.push ( u ) ;
    		int ans = solve () ;
    		printf ( "%d
    " , ans ) ;
    	}
    }




  • 相关阅读:
    Ubuntu安装软件问题的解决
    寻找两个字符串中最长的公共部分字符串
    CentOS
    vim自定义配置
    git创建远程仓库以及在本地提交到远程仓库的方法
    黑金开发板在NiosII环境下烧写image到flash失败的解决办法
    f.lux 一款免费的护眼开源软件
    python 制作自动化脚本
    修改python 默认的存储路径
    第一篇博客
  • 原文地址:https://www.cnblogs.com/whzhaochao/p/5023487.html
Copyright © 2020-2023  润新知