题意:
YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域。简单起见,可以将YT市看作一个
正方形,每一个区域也可看作一个正方形。从而,YT城市中包括(n+1)×(n+1)个交叉路口和2n×(n+1)条双向道路
(简称道路),每条双向道路连接主干道上两个相邻的交叉路口。下图为一张YT市的地图(n = 2),城市被划分为2
×2个区域,包括3×3个交叉路口和12条双向道路。 小Z作为该市的市长,他根据统计信息得到了每天上班高峰期
间YT市每条道路两个方向的人流量,即在高峰期间沿着该方向通过这条道路的人数。每一个交叉路口都有不同的海
拔高度值,YT市市民认为爬坡是一件非常累的事情,每向上爬h的高度,就需要消耗h的体力。如果是下坡的话,则
不需要耗费体力。因此如果一段道路的终点海拔减去起点海拔的值为h(注意h可能是负数),那么一个人经过这段路
所消耗的体力是max{0, h}(这里max{a, b}表示取a, b两个值中的较大值)。 小Z还测量得到这个城市西北角的交
叉路口海拔为0,东南角的交叉路口海拔为1(如上图所示),但其它交叉路口的海拔高度都无法得知。小Z想知道在
最理想的情况下(即你可以任意假设其他路口的海拔高度),每天上班高峰期间所有人爬坡所消耗的总体力和的最
小值。
题解:
终于想出一道平面图的题了(狼抓兔子不算)
首先,xjb猜两个结论:
1:面个点的海拔一定是0或1
2:对于任意一条从左上到右下的路径,一定是前面一段是0,后面一段是1。(显然)
于是对于每一个0,1交界点都要付出一定代价,所以直接建图最小割就好了。
于是网络流愉快的T了。
因为是平面图,所以转对偶图跑最短路就行了。
原来dij比spfa快那么多的啊
code:(AC)
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
#define LL long long
#define pa pair<long long,long long>
using namespace std;
queue<int> q;
LL n,map[510][510][4];const LL inf=1<<29;
struct node{
LL y,c,next;
}a[6400000];LL last[600010],len=0,dis[600010];
bool v[600010];
LL st,ed;
LL read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void ins(LL x,LL y,LL c)
{
a[++len].y=y;a[len].c=c;
a[len].next=last[x];last[x]=len;
}
LL qs(LL x,LL y)
{
if(x>n||y<=1) return ed;
if(x<=1||y>n) return st;
x--;y--;return (x-1)*(n-1)+y;
}
int main()
{
n=read();n++;
memset(map,-1,sizeof(map));
for(LL i=1;i<=n;i++)
for(LL j=1;j<n;j++) map[i][j][0]=read();
for(LL i=1;i<n;i++)
for(LL j=1;j<=n;j++) map[i][j][1]=read();
for(LL i=1;i<=n;i++)
for(LL j=2;j<=n;j++) map[i][j][2]=read();
for(LL i=2;i<=n;i++)
for(LL j=1;j<=n;j++) map[i][j][3]=read();
st=0;ed=n*n+1;
for(LL i=1;i<=n;i++)
for(LL j=1;j<=n;j++)
{
if(j+1<=n) ins(qs(i,j+1),qs(i+1,j+1),map[i][j][0]);
if(i+1<=n) ins(qs(i+1,j+1),qs(i+1,j),map[i][j][1]);
if(j-1>=1) ins(qs(i+1,j),qs(i,j),map[i][j][2]);
if(i-1>=1) ins(qs(i,j),qs(i,j+1),map[i][j][3]);
}
memset(dis,63,sizeof(dis));
memset(v,false,sizeof(v));
priority_queue<pa,vector<pa>,greater<pa> >q;
memset(dis,127,sizeof(dis));dis[st]=0LL;
memset(v,false,sizeof(v));
q.push(make_pair(0,st));
while(!q.empty())
{
int x=q.top().second;q.pop();
if(v[x]) continue;
v[x]=true;
for(int i=last[x];i;i=a[i].next)
{
int y=a[i].y;
if(dis[y]>dis[x]+a[i].c)
{
dis[y]=dis[x]+a[i].c;
q.push(make_pair(dis[y],y));
}
}
}
printf("%lld",dis[ed]);
}
code:(TLE)
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#define LL long long
using namespace std;
LL n,map[510][510][4];const LL inf=1<<29;
struct node{
LL x,y,next,c,other;
}a[6400000];LL last[500010],len=0;
LL h[500010],s[500010],st,ed;
void ins(LL x,LL y,LL c)
{
//printf("%lld->%lld %lld\n",x,y,c);
LL k1=++len;
a[len].x=x;a[len].y=y;a[len].c=c;
a[len].next=last[x];last[x]=len;
LL k2=++len;
a[len].x=y;a[len].y=x;a[len].c=0;
a[len].next=last[y];last[y]=len;
a[k1].other=k2;a[k2].other=k1;
}
bool bt_h()
{
memset(h,0,sizeof(h));
LL l=1,r=2;s[l]=st;h[st]=1;
while(l!=r)
{
LL x=s[l];
for(LL i=last[x];i;i=a[i].next)
{
LL y=a[i].y;
if(h[y]==0&&a[i].c>0) h[y]=h[x]+1,s[r++]=y;
}
l++;
}
return h[ed]!=0;
}
LL findflow(LL x,LL f)
{
if(x==ed) return f;
LL t,ans=0;
for(LL i=last[x];i;i=a[i].next)
{
LL y=a[i].y;
if(h[x]+1==h[y]&&a[i].c>0&&ans<f)
{
ans+=(t=findflow(y,min(a[i].c,f-ans)));
a[i].c-=t;a[a[i].other].c+=t;
}
}
if(ans==0) h[x]=0;
return ans;
}
LL qs(LL x,LL y) {return (x-1)*n+y;}
int main()
{
scanf("%lld",&n);n++;
for(LL i=1;i<=n;i++)
for(LL j=1;j<n;j++) scanf("%lld",&map[i][j][0]);
for(LL i=1;i<n;i++)
for(LL j=1;j<=n;j++) scanf("%lld",&map[i][j][1]);
for(LL i=1;i<=n;i++)
for(LL j=2;j<=n;j++) scanf("%lld",&map[i][j][2]);
for(LL i=2;i<=n;i++)
for(LL j=1;j<=n;j++) scanf("%lld",&map[i][j][3]);
st=1;ed=qs(n,n);
for(LL i=1;i<=n;i++)
for(LL j=1;j<=n;j++)
{
//printf("now:%lld %lld\n",i,j);
if(j+1<=n) ins(qs(i,j),qs(i,j+1),map[i][j][0]);
if(i+1<=n) ins(qs(i,j),qs(i+1,j),map[i][j][1]);
if(j-1>=1) ins(qs(i,j),qs(i,j-1),map[i][j][2]);
if(i-1>=1) ins(qs(i,j),qs(i-1,j),map[i][j][3]);
}
LL ans=0;
while(bt_h()) ans+=(LL)findflow(st,inf);
printf("%lld",ans);
}