BZOJ 2007: [Noi2010]海拔

5 篇文章 0 订阅
3 篇文章 0 订阅

这道题挺不错的。。不难发现都是0和1 原题还有小数迷惑人2333(想想 如果这条边很优 为什么不干脆弄到1?)
然后很快就知道 其实就等于把图分成了割成了两块
那么这就是平面图的最小割了。。
我太菜了 后面就不会了
然后去研究了一下 其实就是平面图转对偶图求最短路 太强了 好劲啊
资料: http://blog.sina.com.cn/s/blog_60707c0f01011fnn.html
其实倒也没有卡spfa 只不过对spfa很不友善
于是我打了个dijkstra 好快啊。。

#include<bits/stdc++.h>
#define me(a,x) memset(a,x,sizeof a)
using namespace std;
const int N=251000;
inline int read()
{
    char ch=getchar(); int x=0,f=1;
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0'; ch=getchar();}
    return x*f;
}
struct node{
    int d,x;
    friend bool operator <(const node &x,const node &y){return x.d>y.d;}
};
struct edge{int y,c,next;}a[N<<2]; int len,first[N];
void ins(int x,int y,int c){a[++len]=(edge){y,c,first[x]},first[x]=len;}
priority_queue<node>q; int d[N],s,t;
void dij()
{
    me(d,63); d[s]=0;
    q.push((node){0,s});
    while(!q.empty())
    {
        node x=q.top(); q.pop();
        if(d[x.x]<x.d)continue;
        for(int k=first[x.x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(d[y]>d[x.x]+a[k].c)
            {
                d[y]=d[x.x]+a[k].c;
                q.push((node){d[y],y});
            }
        }
    }
}
int main()
{
    int n=read(),i,j,c ;s=n*n+1,t=s+1;
    for(i=1;i<=n;i++)c=read(),ins(i,t,c);
    for(i=1;i<n;i++)for(j=1;j<=n;j++)c=read(),ins(i*n+j,(i-1)*n+j,c);
    for(i=1;i<=n;i++)c=read(),ins(s,n*(n-1)+i,c);
    for(i=1;i<=n;i++)
    {
        c=read(),ins(s,(i-1)*n+1,c);
        for(j=1;j<n;j++)c=read(),ins((i-1)*n+j,(i-1)*n+j+1,c);
        c=read(),ins(i*n,t,c);
    }
    for(i=1;i<=n;i++)c=read(),ins(t,i,c);
    for(i=1;i<n;i++)for(j=1;j<=n;j++)c=read(),ins((i-1)*n+j,i*n+j,c);
    for(i=1;i<=n;i++)c=read(),ins(n*(n-1)+i,s,c);
    for(i=1;i<=n;i++)
    {
        c=read(),ins((i-1)*n+1,s,c);
        for(j=1;j<n;j++)c=read(),ins((i-1)*n+j+1,(i-1)*n+j,c);
        c=read(),ins(t,i*n,c);
    }
    dij();
    printf("%d\n",d[t]);
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值