bzoj1001
题解:
网络流求最小割
平面图转对偶图裸题
注意细节就可以了,n or m=1特判
代码:
#include <bits/stdc++.h>
using namespace std;
queue <int> q;
int n,m,l,s,t,x,y;
#define maxn 6000000
int dis[maxn],head[maxn];
bool inq[maxn];
int p[2000][2000];
#define INF 1e9
struct re{
int a,b,c;
}a[maxn];
void arr(int x,int y,int z)
{
a[++l].a=head[x];
a[l].b=y;
a[l].c=z;
head[x]=l;
}
/*void arr(int x,int y,int z)
{
if (f[x][y]==0) f[x][y]=z; else f[x][y]=min(f[x][y],z);
}*/
int main(){ cin>>n>>m;
if (n == 1 || m == 1)
{
if (n > m) swap(n, m);
int ans = INF;
for (int i = 1; i < m; ++i)
{
int x;
cin>>x;
if (x < ans) ans = x;
}
cout<<ans;
exit(0);
}
s=0; t=(n-1)*(m-1)*2+1;
for (int i=1;i<=m-1;i++)
{
cin>>x; arr(0,i,x);arr(i,0,x);
}
for (int j=2;j<=n-1;j++)
for (int i=1;i<=m-1;i++)
{
cin>>y;
int x=(j-1)*(m-1)*2;
arr(x+i,x+i-(m-1),y); arr(x+i-(m-1),x+i,y);
}
for (int i=1;i<=m-1;i++)
{
cin>>y;
arr(t-m+i,t,y); arr(t,t-m+i,y);
}
for (int i=1;i<=n-1;i++)
for (int j=1;j<=m;j++)
cin>>p[i][j];
x=m;
for (int i=1;i<=n-1;i++)
{
y=p[i][1];
arr(x,t,y); arr(t,x,y);
x+=2*(m-1);
}
for (int j=2;j<=m-1;j++)
{
x=m+j-1;
for (int i=1;i<=n-1;i++)
{
y=p[i][j];
arr(x,x-m,y); arr(x-m,x,y);
x+=2*(m-1);
}
}
x=m-1;
for (int i=1;i<=n-1;i++)
{
y=p[i][m];
arr(x,s,y); arr(s,x,y);
x+=2*(m-1);
}
for (int i=1;i<=n-1;i++)
{
int x=(m-1)*2*(i-1)+1;
for (int j=1;j<=m-1;j++)
{
cin>>y;
arr(x,x+(m-1),y); arr(x+(m-1),x,y);
x++;
}
}
/* for (int i=0;i<=t-1;i++)
{
for (int j=0;j<=t;j++)
cout<<i<<" "<<j<<" "<<f[i][j]<<endl;
cout<<endl;
}*/
for (int i=1;i<=t;i++) dis[i]=INF;
q.push(0);
while (!q.empty())
{
int x=q.front(); q.pop();
int u=head[x];
while (u)
{
int v=a[u].b;
if (dis[x]+a[u].c<dis[v])
{
dis[v]=dis[x]+a[u].c;
if (!inq[v])
{
q.push(v); inq[v]=1;
}
}
u=a[u].a;
}
inq[x]=0;
}
cout<<dis[t];
}