zoukankan      html  css  js  c++  java
  • POJ 3026

    真的是一道非常好的习题

    • 首先输入读取上,详见代码可以看到两处trick。一个是格式化字符串中结尾的 ,会在读取到我们所需的之后,将停留在缓存区中的空格(对于只要数字的scanf,POJ discuss处可以看到此处坑了很多人,只读入数字的scanf可以用这种技巧解决这个问题),另一个则是%[^ ]这种正则表达式(不完全是,姑且这么称呼)的使用
    • 而是问题的转化,百思不得其解之后发现其实很简单:首先我们需要每个节点对之间最短距离,对于这种棋盘格的问题,利用bfs生成的广度优先搜索树就可以解决,在求得每个节点对之间最短距离之后,将原问题就等价转化为如何求一棵联通外星人和起点的最小生成树
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    using namespace std;
    
    const int maxw= 55;
    const int maxn= 105;
    const int INF= 0x3f3f3f3f;
    
    int step[4][2]= {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    char mz[maxw][maxw];
    vector<pair<int, int>> pts;
    int n, m, tot;
    int vis[maxw][maxw], dis[maxw][maxw];
    int p_co[maxn], p_v[maxn], co[maxn][maxn];
    
    void BFS(const int s)
    {
    	memset(vis, 0, sizeof(vis));
    	queue<pair<int, int>> Q;
    	vis[pts[s].first][pts[s].second]= 1;
    	dis[pts[s].first][pts[s].second]= 0;
    	Q.push(pts[s]);
    	int x, y;
    	int v;
    
    	while (!Q.empty()){
    		pair<int, int> p= Q.front();
    		Q.pop();
    		v= dis[p.first][p.second];
    		for (int i= 0; i< 4; ++i){
    			x= p.first+step[i][0];
    			y= p.second+step[i][1];
    			if (x< 0 || x>= n || y< 0 || y>= m || '#'== mz[x][y] || vis[x][y]){
    				continue;
    			}
    			vis[x][y]= 1;
    			dis[x][y]= v+1;
    			Q.push(make_pair(x, y));
    		}
    	}
    
    	for (int i= 0; i< tot; ++i){
    		co[s][i]= dis[pts[i].first][pts[i].second];
    	}
    }
    int Prim()
    {
    	for (int i= 1; i< tot; ++i){
    		p_co[i]= co[0][i];
    		p_v[i]= 0;
    	}
    	p_v[0]= 1;
    	p_co[0]= 0;
    	int ans= 0;
    	int minc, p;
    
    	for (int i= 1; i< tot; ++i){
    		minc= INF;
    		p= -1;
    		for (int j= 1; j< tot; ++j){
    			if (!p_v[j] && minc > p_co[j]){
    				minc= p_co[j];
    				p= j;
    			}
    		}
    		if (-1== p){
    			return -1;
    		}
    		ans+= minc;
    		p_v[p]= 1;
    		for (int j= 1; j< tot; ++j){
    			if (!p_v[j] && p_co[j] > co[p][j]){
    				p_co[j]= co[p][j];
    			}
    		}
    	}
    
    
    	return ans;
    }
    
    int main()
    {
    	int kase;
    	scanf("%d", &kase);
    	while (kase--){
    		scanf("%d %d
    ", &m, &n);
    		tot= 0;
    		pts.clear();
    		for (int i= 0; i< n; ++i){
    			scanf("%[^
    ]
    ", mz[i]);
    			for (int j= 0; j< m; ++j){
    				if ('A'== mz[i][j] || 'S'== mz[i][j]){
    					pts.push_back(make_pair(i, j));
    					++tot;
    				}
    			}
    		}
    
    		for (int i= 0; i< tot; ++i){
    			BFS(i);
    		}
    		printf("%d
    ", Prim());
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    雪花降落CADisplayLink
    图片分离--分成两片
    判断是否输入表情符号
    字符串过滤
    UICollectionView Layout自定义 Layout布局
    本地化 NSLocal
    CAAnimation动画--(旋转/缩放/移动/闪烁)
    摇一摇
    监听键盘升降
    ❄️ 雪花降落
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/14660140.html
Copyright © 2011-2022 走看看