大致题意:
见http://www.nocow.cn/index.php/Translate:USACO/castle
大致思路:
苦逼模拟的并查集……usaco里面的还需要输出炸哪一堵墙……崩溃>_<
/* ID:123ldss2 PROG: castle LANG: C++ */ #include<iostream> #include<cstring> #include<cstdio> using namespace std; const int nMax=100005; int father[nMax],rank[nMax],N,M,num[nMax],sum; //rank近似树的高度。 int find(int x){ // 寻找父节点 if(x!=father[x]) return father[x]=find(father[x]); return x; } void unite(int a,int b){ // cout<<a<<" unio "<<b<<endl; int x=find(a); int y=find(b); if(x==y) return ; else{ if(rank[x]>rank[y]){ father[y]=x; num[x]+=num[y]; } else if(rank[x]<rank[y]){ father[x]=y; num[y]+=num[x]; } else{ father[x]=y; num[y]+=num[x]; rank[y]++; } } } void set(){ // 初始化 int i; for(i=0; i<nMax-1; i++){ father[i]=i; rank[i]=0; num[i]=1; } //n=0; } int map[100][100]; bool vis[nMax]; int main(){ int n,m,i,j,ans1,a,b; // freopen ( "castle.in", "r", stdin ); // freopen ( "castle.out", "w", stdout ); while(scanf("%d%d",&n,&m)!=EOF){ set(); sum=0; memset(vis,0,sizeof(vis)); for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ scanf("%d",&map[i][j]); if((map[i][j]&1)==0){ unite((i-1)*m+j,(i-1)*m+j-1); } if((map[i][j]&2)==0){ unite((i-1)*m+j,(i-2)*m+j); } if((map[i][j]&4)==0){ unite((i-1)*m+j,(i-1)*m+j+1); } if((map[i][j]&8)==0){ unite((i-1)*m+j,(i)*m+j); } } } ans1=0; for(i=1;i<=n*m;i++){ j=find(i); // cout<<"num"<<num[find(i)]<<endl; ans1=max(ans1,num[find(i)]); if(vis[j]==0){ vis[j]=1; sum++; } } cout<<sum<<endl; cout<<ans1<<endl; } return 0; }