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\n",l);  
    return 0;  
}  

 

转载于:https://www.cnblogs.com/xuanyiming/p/8304961.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BZOJ 2908 题目是一个数据下载任务。这个任务要求下载指定的数据文件,并统计文件中小于等于给定整数的数字个数。 为了完成这个任务,首先需要选择一个合适的网址来下载文件。我们可以使用一个网络爬虫库,如Python中的Requests库,来帮助我们完成文件下载的操作。 首先,我们需要使用Requests库中的get()方法来访问目标网址,并将目标文件下载到我们的本地计算机中。可以使用以下代码实现文件下载: ```python import requests url = '目标文件的网址' response = requests.get(url) with open('本地保存文件的路径', 'wb') as file: file.write(response.content) ``` 下载完成后,我们可以使用Python内置的open()函数打开已下载的文件,并按行读取文件内容。可以使用以下代码实现文件内容读取: ```python count = 0 with open('本地保存文件的路径', 'r') as file: for line in file: # 在这里实现对每一行数据的判断 # 如果小于等于给定整数,count 加 1 # 否则,不进行任何操作 ``` 在每一行的处理过程中,我们可以使用split()方法将一行数据分割成多个字符串,并使用int()函数将其转换为整数。然后,我们可以将该整数与给定整数进行比较,以判断是否小于等于给定整数。 最后,我们可以将统计结果打印出来,以满足题目的要求。 综上所述,以上是关于解决 BZOJ 2908 数据下载任务的简要步骤和代码实现。 希望对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值