http://acm.hdu.edu.cn/showproblem.php?pid=3870
最大流 转换成 最小割 最小割 转换成 最短路
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<set>
#include<map>
#include<cmath>
#include<algorithm>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
//#define ull unsigned long long
#define ll long long
using namespace std;
const int INF=0x3f3f3f3f;
const ll LINF=1e18;
const int N=400000;
const int M=1000000;
int head[N],I;
struct node
{
int j,next;
int d;
}edge[M];
int dist[N];
bool in[N];
int a[500][500];
void add(int i,int j,int d)
{
edge[I].j=j;
edge[I].d=d;
edge[I].next=head[i];
head[i]=I++;
}
void init(int st,int nd,int n)
{
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
scanf("%d",&a[i][j]);
memset(head,-1,sizeof(head));
I=0;
for(int i=0;i<n-1;++i)
for(int j=0;j<n-1;++j)
{
int l=i*n+j;
if(i==0)
add(l,nd,a[i][j]);
else
add(l,(i-1)*n+j,a[i][j]);
if(j==0)
add(st,l,a[i][j]);
else
add(l,i*n+j-1,a[i][j]);
if(i==n-2)
add(st,l,a[i+1][j]);
else
add(l,(i+1)*n+j,a[i+1][j]);
if(j==n-2)
add(l,nd,a[i][j+1]);
else
add(l,i*n+j+1,a[i][j+1]);
}
}
int spfa(int x1,int x2)
{
memset(in,false,sizeof(in));
memset(dist,-1,sizeof(dist));
queue<int>qt;
qt.push(x1);
dist[x1]=0;
in[x1]=true;
while(!qt.empty())
{
int x=qt.front();
qt.pop();in[x]=false;
for(int t=head[x];t!=-1;t=edge[t].next)
{
int j=edge[t].j;
int d=edge[t].d;
if(dist[j]==-1||dist[j]>dist[x]+d)
{
dist[j]=dist[x]+d;
if(!in[j])
{
in[j]=true;
qt.push(j);
}
}
}
}
return dist[x2];
}
int main()
{
//freopen("data.in","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
int st=n*n;
int nd=st+1;
init(st,nd,n);
printf("%d\n",spfa(st,nd));
}
return 0;
}
浙公网安备 33010602011771号