http://acm.hdu.edu.cn/showproblem.php?pid=3870
平面图转对偶图板题,方法见https://wenku.baidu.com/view/8f1fde586edb6f1aff001f7d.html
平面图的最小割等于对偶图的最短路
#include<bits/stdc++.h>
using namespace std;
const int maxl=410;
const int inf=2e9+10;
int n,m,s,t,tot,ans;
int a[maxl][maxl],num[maxl][maxl];
int dis[maxl*maxl];
struct ed
{
int to,l;
};
vector<ed> e[maxl*maxl];
typedef pair<int,int> p;
priority_queue<p,vector<p>,greater<p> >q;
bool in[maxl*maxl];
inline void prework()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
s=1;t=(n-1)*(n-1)+2;
for(int i=s;i<=t;i++)
e[i].clear();
tot=1;
for(int i=1;i<n;i++)
for(int j=1;j<n;j++)
num[i][j]=++tot;
for(int j=1;j<=n-1;j++)
{
e[s].push_back(ed{num[1][j],a[1][j]});
e[num[1][j]].push_back(ed{s,a[1][j]});
}
for(int i=1;i<=n-1;i++)
{
e[s].push_back(ed{num[i][n-1],a[i][n]});
e[num[i][n-1]].push_back(ed{s,a[i][n]});
}
for(int i=1;i<=n-1;i++)
for(int j=1;j<=n-2;j++)
{
e[num[i][j]].push_back(ed{num[i][j+1],a[i][j+1]});
e[num[i][j+1]].push_back(ed{num[i][j],a[i][j+1]});
}
for(int i=1;i<=n-2;i++)
for(int j=1;j<=n-1;j++)
{
e[num[i][j]].push_back(ed{num[i+1][j],a[i+1][j]});
e[num[i+1][j]].push_back(ed{num[i][j],a[i+1][j]});
}
for(int i=1;i<=n-1;i++)
{
e[num[i][1]].push_back(ed{t,a[i][1]});
e[t].push_back(ed{num[i][1],a[i][1]});
}
for(int j=1;j<=n-1;j++)
{
e[num[n-1][j]].push_back(ed{t,a[n][j]});
e[t].push_back(ed{num[n-1][j],a[n][j]});
}
}
inline void mainwork()
{
for(int i=s;i<=t;i++)
in[i]=false,dis[i]=inf;
dis[1]=0;q.push({dis[1],1});
p d;int u,v;
while(!q.empty())
{
d=q.top();q.pop();
u=d.second;
if(dis[u]!=d.first || in[u])
continue;
in[u]=true;
for(ed b:e[u])
{
v=b.to;
if(in[v] || dis[v]<=dis[u]+b.l)
continue;
dis[v]=dis[u]+b.l;
q.push({dis[v],v});
}
}
ans=dis[t];
}
inline void print()
{
printf("%d\n",ans);
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
prework();
mainwork();
print();
}
return 0;
}