首页 > 代码库 > zoj3781 Paint the Grid Reloaded --- 缩点 bfs
zoj3781 Paint the Grid Reloaded --- 缩点 bfs
╮(╯▽╰)╭水题
相连的相同色块缩成点,和相邻的不同色块建边。
以每一个点为起点bfs,求最小答案。
#include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #define inf 0x3f3f3f3f #define ll long long #define mod 1000000007 using namespace std; char mp[45][45]; int num[1610],cnt,n,m,vis[1610]; int dx[4]={0,0,1,-1}; int dy[4]={1,-1,0,0}; vector<int> v[1600]; struct node { int d,id; }; void dfs(int x,int y,int no,char c) { int i,xx,yy,tmp; for(i=0;i<4;i++) { xx=x+dx[i]; yy=y+dy[i]; if(xx<0||xx>=n||yy<0||yy>=m) continue; if(mp[xx][yy]==c) { if(num[xx*m+yy]==-1)//没有搜过的连通点 { num[xx*m+yy]=no; dfs(xx,yy,no,c); } } else if(num[xx*m+yy]!=-1)//没有搜过的相邻不同颜色的点 { tmp=num[xx*m+yy]; v[no].push_back(tmp); v[tmp].push_back(no); } } } int bfs(int no) { queue<node> q; node tmp,now; tmp.d=0; tmp.id=no; q.push(tmp); int ret=0; memset(vis,0,sizeof vis); vis[tmp.id]=1; while(!q.empty()) { now=q.front(); q.pop(); if(ret<now.d) ret=now.d; tmp.d=now.d+1; for(int j=0;j<v[now.id].size();j++) { tmp.id=v[now.id][j]; if(!vis[tmp.id]) { vis[tmp.id]=1; q.push(tmp); } } } return ret; } int main() { int t,i,j,ans; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=0;i<n;i++) scanf("%s",mp[i]); for(i=0;i<=n*m;i++) v[i].clear(); memset(num,-1,sizeof num); cnt=0; for(i=0;i<n;i++) { for(j=0;j<m;j++) { if(num[i*m+j]==-1) { num[i*m+j]=cnt; dfs(i,j,cnt,mp[i][j]); cnt++; } } } ans=inf; for(i=0;i<cnt;i++) ans=min(ans,bfs(i)); printf("%d\n",ans); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。