1. 程式人生 > >uvaLive7303 Aquarium (最小生成樹)

uvaLive7303 Aquarium (最小生成樹)

stage nbsp urn \n 上下 uva style pri cmp

題意:給R*C的房間,每個房間被左上-右下或右上-左下的墻分割為兩個小房間,將分割移除有一定花費,問使所有小房間聯通需要的最小花費

把每個房間分成左右(上下?)兩個點,判一判,本來就聯通的加零邊,一個房間裏的兩個點間加花費的邊,跑Kruskal即可

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 
 5 using namespace std;
 6 const int maxN=110;
 7 
 8 typedef struct{
 9     int a,b,l;
10
}Edge; 11 12 13 Edge eg[maxN*maxN]; 14 bool stage[maxN][maxN]; //true->\ false->/ 15 int bcj[maxN*maxN*2]; //(i-1)*C+j 16 int T,R,C; 17 18 bool cmp(Edge a,Edge b){ 19 return a.l<b.l; 20 } 21 22 int getf(int i){ 23 return bcj[i]==i?i:bcj[i]=getf(bcj[i]); 24 } 25 26 void add(int a,int
b){ //a->b 27 bcj[getf(a)]=getf(b); 28 } 29 30 int main(){ 31 int t,i,j,k,ind,a,b,num,ans; 32 char cr; 33 34 scanf("%d",&T); 35 for(t=1;t<=T;t++){ 36 scanf("%d%d\n",&R,&C); 37 for(i=1;i<=R;i++){ 38 for(j=1;j<=C;j++){ 39 scanf("
%c",&cr); 40 stage[i][j]=(cr==\\); 41 } 42 if(i<R) scanf("\n"); 43 } 44 ind=0; 45 for(i=1;i<=R;i++){ 46 for(j=1;j<=C;j++){ 47 eg[ind].a=(i-1)*C*2+j*2-1; 48 eg[ind].b=(i-1)*C*2+j*2; 49 scanf("%d",&eg[ind++].l); 50 } 51 } 52 for(i=1;i<=R;i++){ 53 ind=(i-1)*C*2; 54 bcj[ind+1]=ind+1; 55 bcj[ind+C*2]=ind+C*2; 56 for(j=1;j<C;j++){ 57 bcj[ind+j*2]=ind+j*2; 58 bcj[ind+j*2+1]=ind+j*2; 59 } 60 } 61 for(i=1;i<R;i++){ 62 for(j=1;j<=C;j++){ 63 ind=(i-1)*C*2+j*2; 64 a=stage[i][j]?ind-1:ind; 65 b=stage[i+1][j]?ind+C*2:ind+C*2-1; 66 add(a,b); 67 } 68 } 69 sort(eg,eg+R*C,cmp); 70 71 ans=0; 72 for(i=0;i<R*C;i++){ 73 if(getf(eg[i].a)!=getf(eg[i].b)){ 74 add(eg[i].a,eg[i].b); 75 ans+=eg[i].l; 76 } 77 } 78 printf("Case %d: %d\n",t,ans); 79 80 } 81 }

uvaLive7303 Aquarium (最小生成樹)