bzoj2547

题解:

二分+宽搜+KM

显然答案不能太大

然后二分一下

代码:

#include<bits/stdc++.h>    
const int N=115,M=1005;  
using namespace std;  
const int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};  
int m,n,cnt,pt,tot,c[N][N],d[N][N],x,y,t,path[N],bo[N],inq[N][N],mp[N][N];  
struct node{int x,y;}a[N],b[N],h[N+5];
void bfs(int sx,int sy,int p)
{  
    memset(d,0x3f,sizeof(d));
    d[sx][sy]=0;  
    int i,t,head=0,tail=1;
    node u,v;  
    h[1].x=sx;h[1].y=sy;
    memset(inq,0,sizeof(inq));  
    while (head!=tail)
     {  
        head=head%M+1;u=h[head];inq[u.x][u.y]=0;  
        for (int i=0;i<4;i++)
         {  
            v.x=u.x+dx[i];v.y=u.y+dy[i];  
            if (v.x<=0||v.x>m||v.y<=0||v.y>n) continue;  
            if (p^(d[u.x][u.y]&1))  
             if (c[v.x][v.y]<=c[u.x][u.y]) t=0;else t=1;  
            else  
             if (c[v.x][v.y]>=c[u.x][u.y]) t=0;else t=1;  
            if (d[u.x][u.y]+t<d[v.x][v.y])
             {  
                d[v.x][v.y]=d[u.x][u.y]+t;  
                if (!inq[v.x][v.y]){inq[v.x][v.y]=1;tail=tail%M+1;h[tail]=v;}  
             }  
        }  
    }  
}  
int dfs(int x,int lim)
{   
    for (int i=1;i<=tot;i++) 
     if (bo[i]&&mp[x][i]<=lim)
      {  
        bo[i]=0;  
        if (!path[i]||dfs(path[i],lim))
         {  
            path[i]=x;
            return 1;  
         }  
      }  
    return 0;  
}  
int pd(int x)
{  
    int tmp=0;
    memset(path,0,sizeof(path));  
    for (int i=1;i<=(cnt<<1);i++)
     {  
        memset(bo,1,sizeof(bo));  
        tmp+=(dfs(i,x));  
     }  
    return tmp+x>=(cnt<<1);  
}  
int main()
{  
    scanf("%d%d%d%d",&m,&n,&cnt,&pt); 
    for (int i=1;i<=(cnt<<1|1);i++)scanf("%d%d",&a[i].x,&a[i].y);  
    for (int i=1;i<=pt;i++)
     {  
        scanf("%d%d%d",&x,&y,&t);  
        while (t--){b[++tot].x=x;b[tot].y=y;}  
    }  
    for (int i=1;i<=m;i++)  
     for (int j=1;j<=n;j++)scanf("%d",&c[i][j]);  
    for (int i=1;i<=(cnt<<1);i++)
     {  
        if (i<=cnt) bfs(a[i].x,a[i].y,0); else bfs(a[i].x,a[i].y,1);  
        for (int j=1;j<=tot;j++) mp[i][j]=d[b[j].x][b[j].y];  
    }  
    int l=0,r=cnt<<1;  
    while (l<r)
     {  
        int mid=(l+r)>>1;  
        if (pd(mid)) r=mid;
        else l=mid+1;  
     }  
    printf("%d
",l);  
    return 0;  
}  
原文地址:https://www.cnblogs.com/xuanyiming/p/8304961.html