• luoguP2046 [NOI2010]海拔


    题意

    首先贪心地想必定是中间有一道分割线,上面是全是(0),下面全是(1),发现这实际上就是最小割。

    我们直接最小割显然会超时,于是平面图转对偶图求最短路。

    转对偶图:
    所有方向的边的逆时针旋转(90)度,建议自己模拟,这里只给一个西东方向的图。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define pii pair<int,int>
    #define mkp make_pair
    #define fir first
    #define sec second
    const int maxn=510;
    int n,S,T,cnt;
    int head[maxn*maxn];
    ll dis[maxn*maxn];
    bool vis[maxn*maxn];
    struct edge{int to,nxt;ll dis;}e[maxn*maxn*8];
    inline ll read()
    {
    	char c=getchar();ll res=0,f=1;
    	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    	while(c>='0'&&c<='9')res=res*10+c-'0',c=getchar();
    	return res*f;
    }
    inline void add(int u,int v,ll w)
    {
    	e[++cnt].nxt=head[u];
    	head[u]=cnt;
    	e[cnt].to=v;
    	e[cnt].dis=w;
    }
    inline void dijstra()
    {
    	memset(dis,0x3f,sizeof(dis));
    	priority_queue<pii>q;
    	dis[S]=0;q.push(mkp(0,S));
    	while(!q.empty())
    	{
    		int x=q.top().sec;q.pop();
    		if(vis[x])continue;
    		vis[x]=1;
    		for(int i=head[x];i;i=e[i].nxt)
    		{
    			int y=e[i].to;
    			if(dis[y]>dis[x]+e[i].dis)
    			{
    				dis[y]=dis[x]+e[i].dis;
    				q.push(mkp(-dis[y],y));
    			}
    		}
    	}
    }
    int main()
    {
    	//freopen("test.in","r",stdin);
    	//freopen("test.out","w",stdout);
    	n=read();
    	S=0,T=n*n+1;
    	for(int i=1;i<=n+1;i++)
    		for(int j=1;j<=n;j++)
    		{
    			ll k=read();
    			if(i==1)add((i-1)*n+j,T,k);
    			else if(i==n+1)add(S,(n-1)*n+j,k);
    			else add((i-1)*n+j,(i-2)*n+j,k);
    		}
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n+1;j++)
    		{
    			ll k=read();
    			if(j==1)add(S,(i-1)*n+j,k);
    			else if(j==n+1)add(i*n,T,k);
    			else add((i-1)*n+j-1,(i-1)*n+j,k);
    		}
    	for(int i=1;i<=n+1;i++)
    		for(int j=1;j<=n;j++)
    		{
    			ll k=read();
    			if(i==1)add(T,(i-1)*n+j,k);
    			else if(i==n+1)add((n-1)*n+j,S,k);
    			else add((i-2)*n+j,(i-1)*n+j,k);
    		}
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n+1;j++)
    		{
    			ll k=read();
    			if(j==1)add((i-1)*n+j,S,k);
    			else if(j==n+1)add(T,i*n,k);
    			else add((i-1)*n+j,(i-1)*n+j-1,k);
    		}
    	dijstra();
    	printf("%lld",dis[T]);
    }
    
  • 相关阅读:
    Centos 7安装配置NTP网络时间同步服务器
    Git忽略提交规则 .gitignore配置运维总结
    linux scp放后台执行方法
    《Linux Kernel Development》读书笔记PDF下载(2012.5.7最后更新)
    D4整体架构差不多快出来了
    c#实现IOleCommandTarget接口(原闯)
    centos7一键安装samba服务器
    R语言绘图高质量输出
    R语言与数据分析
    R语言Cairo包的使用
  • 原文地址:https://www.cnblogs.com/nofind/p/12104010.html
Copyright © 2020-2023  润新知