bzoj2007: [Noi2010]海拔

Claire_ljy發表於2020-04-04

今天各位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;
}

 

轉載於:https://www.cnblogs.com/AKCqhzdy/p/8869845.html