zoukankan      html  css  js  c++  java
  • 「CodeChef

    题目链接

    戳我

    (Description)

    给你一个(n*m)的网格,以及网格上的两个格子(A,B).每个格子有一个高度.每次操作可以选择一个格子(不能是(A)(B))并将它的高度增加(1).你希望在(A,B)间不存在任何一条不上升路径.求最少操作次数。

    (Solution)

    这道题很容易看出来是最小割啊.

    我们想一想怎么建图.

    最容易想到的是两两之间连边,跑最小割,但是这个很明显是不对的.因为一个点增加了一定的值,可能对别的链有影响,所以不能怎么建图.

    再来想一想,假设我们现在有一个点((x,y)),四个相邻的点大于等于他.

    我们将这四个点的值从小到大排一遍序

    对于(1-3)的点,我们将他们从小编号向他自己的编号(+1)的点连一条流量为这个点的(w-w[x][y]),

    对于(4)这个点,我们将他连向((x,y))这个点,流量也为这个点的(w-w[x][y]).

    最后在将这四个点分别向自己在这四个新建节点中对应点连一条流量为(inf)的边

    注意要特判一下终点和起点,因为这两个点不可以增加高度

    (Code)

    #include<bits/stdc++.h>
    #define inf 1e9
    using namespace std;
    typedef long long ll;
    int read(){
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar();
        while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
        return x*f;
    }
    struct node{
        int to,next,v;
    }a[200001];
    int head[100001],cnt,n,m,s,t,x,y,z,dep[100001],fx,fy,X,Y;
    void add(int x,int y,int c){
        a[++cnt].to=y,a[cnt].next=head[x],a[cnt].v=c,head[x]=cnt;
        a[++cnt].to=x,a[cnt].next=head[y],a[cnt].v=0,head[y]=cnt;
    }
    queue<int> q;
    int bfs(){
        memset(dep,0,sizeof(dep));
        q.push(s);
        dep[s]=1;
        while(!q.empty()){
            int now=q.front();
            q.pop();
            for(int i=head[now];i;i=a[i].next){
                int v=a[i].to;
                if(!dep[v]&&a[i].v>0)
                    dep[v]=dep[now]+1,q.push(v);
            }
        }
        if(dep[t])
            return 1;
        return 0;
    }
    int dfs(int k,int list){
        if(k==t||!list)
            return list;
        for(int i=head[k];i;i=a[i].next){
            int v=a[i].to;
            if(dep[v]==dep[k]+1&&a[i].v>0){
                int p=dfs(v,min(list,a[i].v));
                if(p){
                    a[i].v-=p;
                    if(i&1) a[i+1].v+=p;
                    else a[i-1].v+=p;
                    return p;
                }
            }
        }
        return dep[k]=0;
    }
    int Dinic(){
        int ans=0,k;
        while(bfs())
            while((k=dfs(s,inf)))
                ans+=k;
        if(ans>=inf) return -1;
        return ans;
    }
    int id[101][101],val[101][101],tot;
    int dx[6]={0,0,0,-1,1};
    int dy[6]={0,1,-1,0,0};
    struct node1 {
        int x,y,v;
    }b[10];
    bool cmp(const node1 & a , const node1 & b){
        return a.v<b.v;
    }
    int main(){
        int T=read();
        while(T--){
    	    n=read(),m=read(),s=0,t=n*m*5+1,tot=0,cnt=0;
    	    memset(head,0,sizeof(head));
    	    X=read(),Y=read(),fx=read(),fy=read();
    	    for(int i=1;i<=n;i++)
    	        for(int j=1;j<=m;j++)
    		        id[i][j]=++tot,val[i][j]=read();
    	    add(s,id[X][Y],inf),add(id[fx][fy],t,inf);
    	    for(int i=1;i<=n;i++)
    	        for(int j=1;j<=m;j++){
    		    int res=0;
    		    for(int k=1;k<=4;k++){
    		        int x=i+dx[k],y=j+dy[k];
    		        if(x<1||y<1||x>n||y>m) continue;
    		        if(val[i][j]<=val[x][y])
    			        b[++res].x=x,b[res].y=y,b[res].v=val[x][y];
    		        if((i==X&&j==Y)||(i==fx&&j==fy)){
    			        if(val[i][j]>val[x][y]) add(id[x][y],id[i][j],0);
    			        else add(id[x][y],id[i][j],inf);
    		        }
    		    }
    		    if((i==X&&j==Y)||(i==fx&&j==fy)||res==0)
    		        continue;
    		    sort(b+1,b+1+res,cmp);
    		    for(int k=1;k<res;k++){
    		        int x=b[k].x,y=b[k].y,v=b[k].v;
    		        tot++,add(tot,tot+1,v-val[i][j]+1),add(id[x][y],tot,inf);
        		}
    	    	tot++,add(id[b[res].x][b[res].y],tot,inf),add(tot,id[i][j],b[res].v-val[i][j]+1);
        	}
    	    printf("%d
    ",Dinic());
        }
        return 0;
    }
    
  • 相关阅读:
    跟我学习编写通用的单据编码生成器
    asp.net MVC 框架中控制器里使用Newtonsoft.Json对前端传过来的字符串进行解析
    c#语言中的Process进程类型的使用示例
    C#语言中的XmlSerializer类的XmlSerializer.Deserialize (Stream)方法举例详解
    C#语言中的XmlSerializer类的XmlSerializer.Serialize(Stream,Object)方法举例详解
    大型三甲医院管理系统源码PACS超声科室源码DICOM影像工作站
    大型EMR电子病历源码三甲医院医疗信息管理系统软件网络版
    大型三甲医院信息管理系统源码 His系统功能齐全 完整可用
    大型三甲医院医疗体检信息管理系统源码 PEIS 体检科软件 CS
    大型进销存管理系统源码 家电业 电器类进销存 asp.net C#框架
  • 原文地址:https://www.cnblogs.com/hbxblog/p/10484602.html
Copyright © 2011-2022 走看看