uvaLive7303 Aquarium (kruskal)

题意:给R*C的房间,每个房间被左上-右下或右上-左下的墙分割为两个小房间,将分割移除有一定花费,问使所有小房间联通需要的最小花费

把每个房间分成左右(上下?)两个点,判一判,本来就联通的加零边,一个房间里的两个点间加花费的边,跑kruskal即可

 #include<cstdio>
#include<cstring>
#include<algorithm> using namespace std;
const int maxN=; typedef struct{
int a,b,l;
}Edge; Edge eg[maxN*maxN];
bool stage[maxN][maxN]; //true->\ false->/
int bcj[maxN*maxN*]; //(i-1)*C+j
int T,R,C; bool cmp(Edge a,Edge b){
return a.l<b.l;
} int getf(int i){
return bcj[i]==i?i:bcj[i]=getf(bcj[i]);
} void add(int a,int b){ //a->b
bcj[getf(a)]=getf(b);
} int main(){
int t,i,j,k,ind,a,b,num,ans;
char cr; scanf("%d",&T);
for(t=;t<=T;t++){
scanf("%d%d\n",&R,&C);
for(i=;i<=R;i++){
for(j=;j<=C;j++){
scanf("%c",&cr);
stage[i][j]=(cr=='\\');
}
if(i<R) scanf("\n");
}
ind=;
for(i=;i<=R;i++){
for(j=;j<=C;j++){
eg[ind].a=(i-)*C*+j*-;
eg[ind].b=(i-)*C*+j*;
scanf("%d",&eg[ind++].l);
}
}
for(i=;i<=R;i++){
ind=(i-)*C*;
bcj[ind+]=ind+;
bcj[ind+C*]=ind+C*;
for(j=;j<C;j++){
bcj[ind+j*]=ind+j*;
bcj[ind+j*+]=ind+j*;
}
}
for(i=;i<R;i++){
for(j=;j<=C;j++){
ind=(i-)*C*+j*;
a=stage[i][j]?ind-:ind;
b=stage[i+][j]?ind+C*:ind+C*-;
add(a,b);
}
}
sort(eg,eg+R*C,cmp); ans=;
for(i=;i<R*C;i++){
if(getf(eg[i].a)!=getf(eg[i].b)){
add(eg[i].a,eg[i].b);
ans+=eg[i].l;
}
}
printf("Case %d: %d\n",t,ans); }
}
上一篇:MySQL8.0.21 root 密码登陆不入-ERROR 1045(28000) Access denied for user 'root'@'localhost' (using password YES)


下一篇:关于Python, ftplib模块中的cwd()进入含中文目录失败的问题