CF590C Three States(搜索)
我们把每个种族看作一个集合
已知最后他们联通,那么这就意味着他们到达某一点联通的代价是最小的
因此我们枚举所有点,找到最小值。
事实上,最后答案的连通块上面的点都是最小的,他们没有区别
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll,ll> pll; const int N=3e7+10; const int mod=1e9+7; char s[1010][1010]; int n,m; int dis[1010][1010][4]; int dx[]={-1,0,1,0}; int dy[]={0,1,0,-1}; void bfs(int x){ queue<pll> q; int i,j; for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ if(s[i][j]=='0'+x){ q.push({i,j}); dis[i][j][x]=0; } } } while(q.size()){ auto t=q.front(); q.pop(); int i; for(i=0;i<4;i++){ int a=t.first+dx[i]; int b=t.second+dy[i]; if(a>=1&&a<=n&&b>=1&&b<=m){ if(s[a][b]=='#') continue; int v=(s[a][b]=='.'); if(dis[a][b][x]>dis[t.first][t.second][x]+v){ dis[a][b][x]=dis[t.first][t.second][x]+v; q.push({a,b}); } } } } } int main(){ ios::sync_with_stdio(false); cin>>n>>m; int i,j; memset(dis,0x3f,sizeof dis); for(i=1;i<=n;i++){ for(j=1;j<=m;j++) cin>>s[i][j]; } bfs(1); bfs(2); bfs(3); ll ans=1e18; for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ if(s[i][j]=='#') continue; ll tmp=0; for(int k=1;k<=3;k++){ tmp+=dis[i][j][k]; } if(s[i][j]=='.') tmp-=2; ans=min(ans,tmp); } } if(ans>1e9){ cout<<-1<<endl; } else cout<<ans<<endl; return 0; }
没有人不辛苦,只有人不喊疼