BZOJ3619 [Zjoi2014]璀燦光華
阿新 • • 發佈:2018-07-08
oid 組成 dig nod 最大值 first stdin 左右 min
題意:有一個\(a^3\)個小正方體組成的大正方體,其中有n個正方體會向上下左右前後六個方向中的一個發出光,正方體是透光的,被照亮的正方體有個美麗值\(g_{i}\),給出正方體的相鄰關系,問美麗值之和的最小值和最大值。
難點在如何建圖。
先隨便找個棱角,再隨便建兩條棱,然後一層一層鋪下去。當鋪到一個新的點時,肯定已經鋪好了至少一個與它相鄰的點,然後再暴力算出已知與當前點相鄰的點給出的每個相鄰的點的出現次數,然後沒被填過且出現次數最多的那個點的編號,就是當前點的編號。
建完圖跑個dfs就行了。
#include<cstdio> #include<algorithm> #include<string> #include<cstring> #include<iostream> using namespace std; #define ll long long #define For(i,x,y) for (register int i=(x);i<=(y);i++) #define Dow(i,x,y) for (register int i=(x);i>=(y);i--) #define cross(i,k) for (register int i=first[k];i;i=last[i]) char c; inline ll read(){ ll x=0;int ch=getchar(),f=1; while (!isdigit(ch)&&(ch!=‘-‘)&&(ch!=EOF)) ch=getchar(); if (ch==‘-‘){f=-1;ch=getchar();} while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-‘0‘;ch=getchar();} c=ch;return x*f; } const int N = 70*70*70+10; const int dx[6]={1,-1,0,0,0,0}; const int dy[6]={0,0,1,-1,0,0}; const int dz[6]={0,0,0,0,1,-1}; struct node{ int x,y,z; }l[11]; int n,rt,tot,g[N],next[N][7],a[75][75][75],vis[N],cnt[N]; ll Max,Min; inline bool check(int x,int y,int z){return x>0&&x<=n&&y>0&&y<=n&&z>0&&z<=n;} inline void dfs(int now,int x,int y,int z,int k){ a[x][y][z]=now,vis[now]=1; if (z==n&&k==4||y==n&&k==2) return; if (z==n-1&&k==4||y==n-1&&k==2){ For(i,1,next[now][0]){ int v=next[now][i]; if (!vis[v]&&next[v][0]==3){dfs(v,x+dx[k],y+dy[k],z+dz[k],k);break;} } return; } For(i,1,next[now][0]){ int v=next[now][i]; if (!vis[v]&&next[v][0]==4){dfs(v,x+dx[k],y+dy[k],z+dz[k],k);break;} } } int x,y,z,Vis[75][75][75]; ll ans; inline ll min(ll a,ll b){return a<b?a:b;} inline ll max(ll a,ll b){return a>b?a:b;} inline void dfs(int k){ if (k>tot){Max=max(Max,ans),Min=min(Min,ans);return;} For(i,0,5){ x=l[k].x,y=l[k].y,z=l[k].z; while (check(x+dx[i],y+dy[i],z+dz[i])){ x+=dx[i],y+=dy[i],z+=dz[i]; if (!Vis[x][y][z]) ans+=1ll*g[a[x][y][z]];Vis[x][y][z]++; } dfs(k+1); x=l[k].x,y=l[k].y,z=l[k].z; while (check(x+dx[i],y+dy[i],z+dz[i])){ x+=dx[i],y+=dy[i],z+=dz[i],Vis[x][y][z]--; if (!Vis[x][y][z]) ans-=1ll*g[a[x][y][z]]; } } } inline void Print(){ For(i,1,n){ For(j,1,n){ For(k,1,n) printf("%d ",a[i][j][k]);puts(""); }puts(""); } } int main(){ //freopen("P3342.in","r",stdin); //freopen("P3342.out","w",stdout); n=read(); For(i,1,n*n*n){ g[i]=read(); while (c==‘ ‘) next[i][++next[i][0]]=read(); } For(i,1,n*n*n) if (next[i][0]==3){rt=i;break;} dfs(rt,1,1,1,4),dfs(rt,1,1,1,2); For(i,1,n) For(j,1,n) For(k,1,n){ if (a[i][j][k]) continue; int Max=0,Max_id=0; for (int d=0;d<6;d+=2){ int v=a[i-dx[d]][j-dy[d]][k-dz[d]]; For(nxt,1,next[v][0]){ cnt[next[v][nxt]]++; if (cnt[next[v][nxt]]>Max&&!vis[next[v][nxt]]) Max=cnt[next[v][nxt]],Max_id=next[v][nxt]; } } a[i][j][k]=Max_id,vis[Max_id]=1; for (int d=0;d<6;d+=2){ int v=a[i-dx[d]][j-dy[d]][k-dz[d]]; For(nxt,1,next[v][0]) cnt[next[v][nxt]]--; } } For(i,1,n) For(j,1,n) For(k,1,n) if (!g[a[i][j][k]]) l[++tot]=(node){i,j,k}; Max=(ll)-1e18,Min=-Max; dfs(1); printf("%lld %lld",Min,Max); }
BZOJ3619 [Zjoi2014]璀燦光華