bzoj2007: [Noi2010]海拔

今天各位D初一小猴子的情景

你学网络流?

来来来师兄给你来几题?

无源汇有上下界费用流会不会?

最大权闭合子图会不会?

黑白染色会不会?

这都不会?

菜鸡yzh:你能不能不用网络流做狼抓兔子

。。。

然而随便点开这题

诶NOI的题会这么水要么高度为1要么为0?

啊不就是平面图转对偶图?

然后一开始以为回边是没用的。。。图又建错一次。。。。

dij才是正解,但是呢spfa可以狗过。。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

struct node
{
    int x,y,d,next;
}a[4100000];int len,last[310000];
void ins(int x,int y,int d)
{
    len++;
    a[len].x=x;a[len].y=y;a[len].d=d;
    a[len].next=last[x];last[x]=len;
}

int list[310000];bool v[310000];
int d[310000];
int main()
{
    freopen("altitude.in","r",stdin);
    freopen("altitude.out","w",stdout);
    int n,dd,st,ed;
    scanf("%d",&n);st=n*n+1,ed=n*n+2;
    for(int i=1;i<=n+1;i++)
    {
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&dd);
            if(i==1)
                ins(st,j,dd);
            else if(i==n+1)
                ins(n*(n-1)+j,ed,dd);
            else
                ins(n*(i-2)+j,n*(i-1)+j,dd);
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n+1;j++)
        {
            scanf("%d",&dd);
            if(j==1)
                ins(n*(i-1)+j,ed,dd);
            else if(j==n+1)
                ins(st,n*i,dd);
            else
                ins(n*(i-1)+j,n*(i-1)+j-1,dd);
        }
    }
    for(int i=1;i<=n+1;i++)
    {
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&dd);
            if(i==1)
                ins(j,st,dd);
            else if(i==n+1)
                ins(ed,n*(n-1)+j,dd);
            else
                ins(n*(i-1)+j,n*(i-2)+j,dd);
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n+1;j++)
        {
            scanf("%d",&dd);
            if(j==1)
                ins(ed,n*(i-1)+j,dd);
            else if(j==n+1)
                ins(n*i,st,dd);
            else
                ins(n*(i-1)+j-1,n*(i-1)+j,dd);
        }
    }
    
    //---------composition--------------------
    
    memset(d,63,sizeof(d));d[st]=0;
    memset(v,false,sizeof(v));v[st]=true;
    int head=1,tail=2;list[1]=st;
    while(head!=tail)
    {
        int x=list[head];
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(d[y]>d[x]+a[k].d)
            {
                d[y]=d[x]+a[k].d;
                if(v[y]==false)
                {
                    v[y]=true;
                    list[tail]=y;
                    tail++;if(tail==301000)tail=1;
                }
            }
        }
        v[x]=false;
        head++;if(head==301000)head=1;
    }
    printf("%d\n",d[ed]);
    return 0;
}

 

posted @ 2018-04-17 20:30  AKCqhzdy  阅读(146)  评论(0编辑  收藏  举报