UVALive 7303Aquarium 最小生成树

来源:互联网 发布:而立不惑知天命的含义 编辑:程序博客网 时间:2024/06/06 20:50
题意:给定一个n*m的方格,每个方格都由'/'或'\'来分隔成两个部分,假设他们是一堵墙,有它的坚硬程度,
现在需要打破其中一些墙,来使得每个格子都连通,并且所需的坚硬值最小。
思路:连通性问题并要求权值最小,那就是最小生成树的问题了,建图,因为每个格子都分隔成两个部分,所以
  所以给这两个部分编号,墙壁的坚硬值就是连接这两部分的权值,再分类讨论一下,这两部分与其周围相邻
          部分的联通情况,权值为0,仔细考虑就不会写错,为了方便表示,规定每个格子的上半部分比下半部分的编

         号小1,最后来一遍最小生成树就可以了。

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <vector>#include <map>#include <cmath>#include <set>#include <queue>using namespace std;const int INF=1e9+10;const double EPS = 1e-10;  typedef long long ll;int v[105][105],cnt[105][105];char mp[105][105];struct edge{int u,v,cost;};bool cmp(edge a,edge b){return a.cost<b.cost;}edge es[100000];int par[200050];void init(int n){for(int i=0;i<=n;i++){par[i]=i;}}int find(int x){if(par[x]==x)return x;elsereturn par[x]=find(par[x]);}void unite(int x,int y){x=find(x);y=find(y);if(x!=y)par[x]=y;}bool same(int x,int y){return find(x)==find(y);}ll solve(int n,int k){init(n);ll res=0;sort(es,es+k,cmp);for(int i=0;i<k;i++){edge e=es[i];if(!same(e.u,e.v)){unite(e.u,e.v);res+=1LL*e.cost;}}return res;}int main(){//freopen("out.txt","w",stdout);int t;scanf("%d",&t);int cas=1;while(t--){int n,m;scanf("%d %d",&n,&m);for(int i=0;i<n;i++){scanf("%s",mp[i]);}int k=0;for(int i=0;i<n;i++)for(int j=0;j<m;j++){scanf("%d",&v[i][j]);cnt[i][j]=k;k+=2;}int mxnode=k-1;k=0;for(int i=0;i<n;i++){for(int j=0;j<m;j++){int a=cnt[i][j];int b=a+1;es[k++]=(edge){a,b,v[i][j]};if(mp[i][j]=='/'){int x1=i-1,y1=j-1;if(x1>=0){es[k++]=(edge){a,cnt[x1][j]+1,0};}if(y1>=0){if(mp[i][y1]=='/')es[k++]=(edge){a,cnt[i][y1]+1,0};elsees[k++]=(edge){a,cnt[i][y1],0};}x1=i+1,y1=j+1;if(x1<n){es[k++]=(edge){b,cnt[x1][j],0};}if(y1<m){if(mp[i][y1]=='/')es[k++]=(edge){b,cnt[i][y1],0};elsees[k++]=(edge){b,cnt[i][y1]+1,0};}}else{int x1=i-1,y1=j+1;if(x1>=0){es[k++]=(edge){a,cnt[x1][j]+1,0};}if(y1<m){if(mp[i][y1]=='/')es[k++]=(edge){a,cnt[i][y1],0};elsees[k++]=(edge){a,cnt[i][y1]+1,0};}x1=i+1,y1=j-1;if(x1<n){es[k++]=(edge){b,cnt[x1][j],0};}if(y1>=0){if(mp[i][y1]=='/')es[k++]=(edge){b,cnt[i][y1]+1,0};elsees[k++]=(edge){b,cnt[i][y1],0};}}}}ll ans=solve(mxnode,k);//printf("Case %d: %lld\n",cas++,ans );cout<<"Case "<<cas++<<": "<<ans<<endl;}    return 0;  }


0 0