codevs 1002 dfs+最小生成树(建图!!)

来源:互联网 发布:ucl data science 知乎 编辑:程序博客网 时间:2024/04/27 22:25
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;int n,m,mark[51][51],cnt,ans,sum,fa[2001];bool mp[51][51];int xx[8]={-1,-1,-1,0,0,1,1,1};int yy[8]={-1,0,1,-1,1,-1,0,1};struct data{    int x,y,v;}e[100001];bool cmp(data a,data b){    return a.v<b.v;}int Find(int x){    return fa[x]==x?x:fa[x]=Find(fa[x]);}bool add(int x1,int y1,int x2,int y2,int v){    if(y2<1||y2>m||x2<1||x2>n||!mark[x2][y2])return 1;    if(mark[x1][y1]==mark[x2][y2])return 0;    cnt++;    e[cnt].x=mark[x1][y1];    e[cnt].y=mark[x2][y2];    e[cnt].v=v-1;    return 1;}int dfs(int x,int y){    mark[x][y]=ans;    for(int i=0;i<8;i++){        int nowx=x+xx[i],nowy=y+yy[i];        if(mp[nowx][nowy]&&!mark[nowx][nowy])            dfs(nowx,nowy);    }}void work1(){    ans=0;    for(int i=1;i<=n;i++){        for(int j=1;j<=m;j++){            if(mp[i][j]&&!mark[i][j]){                ans++;dfs(i,j);            }        }    }    printf("%d\n",ans);}void build(int x,int y){    for(int i=x+1;i<=n;i++)        if(!add(x,y,i,y,i-x)||!add(x,y,i,y+1,i-x)||!add(x,y,i,y-1,i-x))            break;    for(int i=x-1;i>0;i--)        if(!add(x,y,i,y,x-i)||!add(x,y,i,y+1,x-i)||!add(x,y,i,y-1,x-i))            break;    for(int i=y+1;i<=m;i++)        if(!add(x,y,x,i,i-y)||!add(x,y,x-1,i,i-y)||!add(x,y,x+1,i,i-y))            break;    for(int i=y-1;i>0;i--)        if(!add(x,y,x,i,y-i)||!add(x,y,x-1,i,y-i)||!add(x,y,x+1,i,y-i))            break;}void work2(){    for(int i=1;i<=n;i++){        for(int j=1;j<=m;j++){            if(mp[i][j])build(i,j);        }    }    sort(e+1,e+cnt+1,cmp);     for(int i=1;i<=ans;i++)fa[i]=i;     ans=0;     for(int i=1;i<=cnt;i++){        int t1=Find(e[i].x),t2=Find(e[i].y);        if(t1!=t2){fa[t1]=fa[t2];ans++;sum+=e[i].v;}    }    printf("%d %d\n",ans,sum);}int main(){     scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++){        char ch[60];        scanf("%s",ch);        for(int j=1;j<=m;j++)            if(ch[j-1]=='#')mp[i][j]=1;    }    work1();    work2();    return 0;}
0 0
原创粉丝点击