用并查集写的,思路与TJ差不多
(模拟赛时破天荒地推出来的思路),卡85分调不出来。。。
这是本蒟蒻第一道思路最清晰の紫,真心求调
马蜂可能很丑,见谅
原题.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
vector<vector<int> > a,b,sum,use;
int x[1000006],y[1000006],cnt[1000006],bian[1000006];
inline int jl(int x1,int y1,int x2,int y2){
return abs(x1-x2)+abs(y1-y2);
}
int gx[4]={-1,1,0,0},gy[4]={0,0,-1,1};
int fa[1000006],shi[1000006],dian[1000006];
int fmn[1000006];
int getf(int x){
//cout<<"X: "<<x<<" "<<fa[x]<<endl;
if(x==fa[x]){
return x;
}
int ft=getf(fa[x]);
//cout<<x<<" "<<ft<<endl;
fa[x]=ft;dian[x]=dian[ft];
shi[x]=shi[ft];
return ft;
}
inline void change(int x,int y){
//cout<<x<<" "<<y<<" "<<fa[x]<<" "<<fa[y]<<endl;
int fx=getf(x);
int fy=getf(y);
if(fx==fy) return;
fa[fx]=fy;dian[fy]+=dian[fx];
shi[fy]|=shi[fx];
//cout<<"BING: "<<x<<" "<<y<<" "<<fx<<" "<<fy<<" "<<shi[fy]<<" "<<shi[fx]<<endl;
}
int fsum;
int main(){
// freopen("mlynar.in","r",stdin);
// freopen("mlynar.out","w",stdout);
int n,m;scanf("%d%d",&n,&m);
if(n==1||m==1){
cout<<"No";return 0;
}
a.resize(n+10);b.resize(n+10);
sum.resize(n+10);use.resize(n+10);
a[0].resize(m+10);b[0].resize(m+10);
sum[0].resize(m+10);use[0].resize(m+10);
for(int i=1;i<=n;i++){
a[i].resize(m+10);b[i].resize(m+10);
sum[i].resize(m+10);use[i].resize(m+10);
for(int j=1;j<=m;j++){
scanf("%d",&a[i][j]);
}
}
for(int i=n+1;i<=n+3;i++){
a[i].resize(m+10);b[i].resize(m+10);
sum[i].resize(m+10);use[i].resize(m+10);
}
int k;scanf("%d",&k);
for(int i=1;i<=k;i++){
scanf("%d%d",&x[i],&y[i]);
fa[i]=i;shi[i]=0;dian[i]=1;//并查集
x[i]++;y[i]++;cnt[i]=1;
if((x[i]==1||x[i]==n)&&(y[i]==1||y[i]==m)){
cout<<"No";return 0;
}
if((x[i]==1||x[i]==n)||(y[i]==1||y[i]==m)){
cnt[i]=0;
}
//cout<<"CAN "<<x[i]<<" "<<y[i]<<endl;
b[x[i]][y[i]]=i;
sum[x[i]][y[i]]++;
//cout<<"CAN"<<endl;
for(int j=0;j<4;j++){
int x1=x[i]+gx[j],y1=y[i]+gy[j];
//cout<<x1<<" "<<y1<<endl;
sum[x1][y1]++;
}
}//cout<<"CAN\n";
/*for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cout<<b[i][j]<<" ";
}cout<<endl;
}*/
for(int i=1;i<=k;i++){
int tsum=0;
for(int tx=max(1,x[i]-1);tx<=min(n,x[i]+1);tx++){
for(int ty=max(1,y[i]-1);ty<=min(m,y[i]+1);ty++){
tsum+=(bool)(b[tx][ty]);
}
}
if(tsum-1>1){
cout<<"No";return 0;
}
}
for(int i=1;i<=k;i++){
//cout<<i<<endl;
//cout<<x[i]<<" "<<y[i]<<endl;
for(int tx=max(1,x[i]-2);tx<=min(n,x[i]+2);tx++){
for(int ty=max(1,y[i]-2);ty<=min(m,y[i]+2);ty++){
if(jl(tx,ty,x[i],y[i])>2) continue;
/*cout<<tx<<" "<<ty<<" "<<x[i]<<" "<<y[i]<<endl;
if(b[tx][ty]){
cout<<"CAN\n";
}*/
cnt[i]+=(bool)(b[tx][ty]);
}
}
cnt[i]--;
//cout<<i<<" "<<cnt[i]<<endl;
cnt[i]-=(sum[x[i]][y[i]]-1);
for(int j=0;j<4;j++){
int x1=x[i]+gx[j],y1=y[i]+gy[j];
cnt[i]-=(sum[x1][y1]-1);
}
if(cnt[i]<0){
cout<<"No";return 0;
}
if(cnt[i]==0){
shi[i]=1;
}
for(int tx=max(1,x[i]-2);tx<=min(n,x[i]+2);tx++){
for(int ty=max(1,y[i]-2);ty<=min(m,y[i]+2);ty++){
if(jl(tx,ty,x[i],y[i])>2) continue;
if(b[tx][ty]){
//cout<<b[tx][ty]<<" "<<tx<<" "<<ty<<endl;
//cout<<"CAN1 "<<i<<" "<<b[tx][ty]<<" "<<x[i]<<" "<<y[i]<<" "<<tx<<" "<<ty<<endl;
change(i,b[tx][ty]);
//cout<<"CAN2\n";
}
}
}
}
memset(fmn,0x3f,sizeof(fmn));
for(int i=1;i<=k;i++){
int fx=getf(i);
if(shi[fx]) continue;
for(int j=0;j<4;j++){
int x1=x[i]+gx[j],y1=y[i]+gy[j];
if(b[x1][y1]) continue;
fmn[fx]=min(fmn[fx],a[x1][y1]);
}
}
for(int i=1;i<=k;i++){
if(!use[x[i]][y[i]]){
fsum+=a[x[i]][y[i]];
int fx=getf(i);
bian[fx]+=(sum[x[i]][y[i]]-1);
use[x[i]][y[i]]=1;
}
for(int j=0;j<4;j++){
int x1=x[i]+gx[j],y1=y[i]+gy[j];
if(b[x1][y1]||use[x1][y1]) continue;
int fx=getf(i);
bian[fx]+=(sum[x1][y1]-1);
fsum+=a[x1][y1];use[x1][y1]=1;
}
}
for(int i=1;i<=k;i++){
int fx=getf(i);
if(fx==i){
if(bian[i]>dian[i]){
cout<<"No";return 0;
}
}
if(fx==i&&!shi[i]){
fsum-=fmn[i];
}
}
cout<<fsum;
return 0;
}
/*
7 6
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
5
1 1
1 3
3 1
3 3
1 4
*/