如果只放一个点,很显然就是放在直径的中点上面,这样一定是最优的,
而现在题目要求断开一条边,然后使得两个部分的最长直径最短。
考虑断开这条边的位置,一定是在原来那棵树的直径上面。
于是呢,就把直径抽出来,
求出断开每一条边的上半部分跟下半部分的直径分别是多少,
然后组合一下就好了。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define N 13
#define M 103
#define db double
#define P putchar
#define G getchar
#define inf 998244353
#define pi 3.1415926535897932384626433832795
using namespace std;
char ch;
void read(int &n)
{
n=0;
ch=G();
while((ch<'0' || ch>'9') && ch!='-')ch=G();
ll w=1;
if(ch=='-')w=-1,ch=G();
while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G();
n*=w;
}
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return aabs(ll x){return x<0?-x:x;}
ll sqr(ll x){return x*x;}
void write(ll x){if(x>9) write(x/10);P(x%10+'0');}
int a[N][N],b[N][N],ans[N][N],num;
int bel[N][N],s[N*N],si[N*N],m,n;
int fx[4][2]={{-1,0},{0,-1},{0,1},{1,0}};
bool t1[N][10],t2[N][10];
struct node
{
int x,y,si,cnt;
}w[N*N];
bool cmp(node a,node b)
{
return a.sivoid dfs(int x,int y,int t)
{
int xx,yy;
for(int i=0;i<4;i++)
{
xx=x+fx[i][0];
yy=y+fx[i][1];
if(xx<1 || yy<1 || xx>n ||yy>n)continue;
if(!bel[xx][yy] && a[xx][yy]==t)si[bel[xx][yy]=bel[x][y]]++,dfs(xx,yy,t);
}
}
bool check()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(ans[i][j]return 0;
if(ans[i][j]>b[i][j])return 1;
}
return 0;
}
void dg(int now)
{
int id,x=w[now].x,y=w[now].y;
if(now>n*n)
{
num++;
if(check())memcpy(ans,b,sizeof(ans));
return;
}
for(int i=1;i<10;i++)
if(t1[x][i] && t2[y][i])
{
id=bel[x][y];
if(s[id]%i)continue;
if(si[id]==1 && (s[id]^i))continue;
si[id]--;s[id]=s[id]/i;
b[x][y]=i;t1[x][i]=t2[y][i]=0;
dg(now+1);
si[id]++;s[id]=s[id]*i;
t1[x][i]=t2[y][i]=1;
}
}
int main()
{
freopen("kenken.in","r",stdin);
freopen("kenken.out","w",stdout);
read(n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
read(a[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(!bel[i][j])
{
s[bel[i][j]=++m]=a[i][j];
si[m]=1;
dfs(i,j,a[i][j]);
}
w[i*n-n+j].x=i;
w[i*n-n+j].y=j;
w[i*n-n+j].si=a[i][j];
w[i*n-n+j].cnt=bel[i][j];
}
sort(w+1,w+1+n*n,cmp);
memset(t1,1,sizeof(t1));
memset(t2,1,sizeof(t2));
ans[1][1]=N,dg(1);
write(num);P('\n');
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
write(ans[i][j]),P(' ');
P('\n');
}
return 0;
}