学会了用最短路求平面图的最大流。
http://blog.sina.com.cn/s/blog_60707c0f01011fnn.html
代码
#include<bits/stdc++.h>
#define rep(i,a,b) for(ll i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const ll maxn = 2e6;
const ll inf = 0x3f3f3f3f;
struct Edge
{
ll from,to,dist;
};
struct HeapNode
{
ll d,u;
bool operator < (const HeapNode& rhs) const
{
return d>rhs.d;
}
};
struct Dijkstra
{
ll n,m;
vector<Edge>edges;
vector<ll>G[maxn];
ll d[maxn],done[maxn];
void init(ll n)
{
this->n=n;
rep(i,0,n-1) G[i].clear();
edges.clear();
}
void add(ll u,ll v,ll d)
{
edges.push_back((Edge){u,v,d});
edges.push_back((Edge){v,u,d});
m=edges.size();
G[u].push_back(m-2);
G[v].push_back(m-1);
}
void dijkstra(ll s)
{
rep(i,0,n-1)
{
d[i]=inf;
done[i]=0;
}
d[s]=0;
priority_queue<HeapNode>Q;
Q.push((HeapNode){0,s});
while(!Q.empty())
{
HeapNode x=Q.top();Q.pop();
ll u=x.u;
if(done[u]) continue;
done[u]=1;
ll sz=G[u].size();
rep(i,0,sz-1)
{
Edge& e=edges[G[u][i]];
if(d[e.to]>d[e.from]+e.dist)
{
d[e.to]=d[e.from]+e.dist;
Q.push((HeapNode){d[e.to],e.to});
}
}
}
}
};
ll n,m;
ll tp;
Dijkstra DIJ;
ll kase;
ll id(ll i,ll j,ll k)
{
return 2*(i*(m-1)+j)+k;
}
int main()
{
while(scanf("%lld %lld",&n,&m)==2&&n&&m)
{
DIJ.init((n-1)*(m-1)*2+2);
ll s=(n-1)*(m-1)*2;
ll t=(n-1)*(m-1)*2+1;
rep(i,0,n-1) rep(j,0,m-2)
{
scanf("%lld",&tp);
if(i==0) DIJ.add(id(i,j,1),t,tp);
else if(i==n-1) DIJ.add(s,id(i-1,j,0),tp);
else DIJ.add(id(i,j,1),id(i-1,j,0),tp);
}
rep(i,0,n-2) rep(j,0,m-1)
{
scanf("%lld",&tp);
if(j==0) DIJ.add(s,id(i,j,0),tp);
else if(j==m-1) DIJ.add(id(i,j-1,1),t,tp);
else DIJ.add(id(i,j-1,1),id(i,j,0),tp);
}
rep(i,0,n-2) rep(j,0,m-2)
{
scanf("%lld",&tp);
DIJ.add(id(i,j,0),id(i,j,1),tp);
}
DIJ.dijkstra(s);
printf("Case %lld: Minimum = %lld\n",++kase,DIJ.d[t]);
}
return 0;
}