【BeiJing2006】【BZOJ1001】狼抓兔子

Description

现在小朋友们最喜欢的”喜羊羊与灰太狼”,话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:
这里写图片描述

左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上角和右下角为兔子的两个窝,开始时所有的兔子都聚集在左上角(1,1)的窝里,现在它们要跑到右下解(N,M)的窝中去,狼王开始伏击这些兔子.当然为了保险起见,如果一条道路上最多通过的兔子数为K,狼王需要安排同样数量的K只狼,才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的狼的数量要最小。因为狼还要去找喜羊羊麻烦.
Input

第一行为N,M.表示网格的大小,N,M均小于等于1000.接下来分三部分第一部分共N行,每行M-1个数,表示横向道路的权值. 第二部分共N-1行,每行M个数,表示纵向道路的权值. 第三部分共N-1行,每行M-1个数,表示斜向道路的权值. 输入文件保证不超过10M
Output

输出一个整数,表示参与伏击的狼的最小数量.
Sample Input
3 4
5 6 4
4 3 1
7 5 3
5 6 7 8
8 7 6 5
5 5 5
6 6 6
Sample Output
14
HINT

2015.4.16新加数据一组,可能会卡掉从前可以过的程序。

Source

一眼看出是最小割
但是直接写最大流就萎了…因为有10^6个点(当然是因为我的最大流比较丑跑得慢)
所以学平面图的时候顺便学了平面图和对偶图的关系
这个题给的图一看就是个很明显的平面图
对它建出对偶图之后应用最短路和最小割之间的对应关系以网络流的源点为起点跑一遍Heap-Dijkstra
最后到汇点的最短路距离就是原图的最小割答案.
跟着黄学长学了平面图转对偶图的姿势.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define MAXN 2000100
using namespace std;
int n,m,size,top;
struct edge
{
    int to,w;
    edge *next;
}e[MAXN<<2],*prev[MAXN];
void in(int &x)
{
    x=0;char ch=getchar();int flag=1;
    while (!(ch>='0'&&ch<='9')) flag=ch=='-'?-1:flag,ch=getchar();
    while (ch>='0'&&ch<='9')    x=x*10+ch-'0',ch=getchar();x*=flag;
}
struct node
{
    int x,dis;
    bool operator <(const node& a)const
    {
        return dis>a.dis;
    }
};
priority_queue<node> q;
int dis[MAXN];
bool vis[MAXN];
void insert(int u,int v,int w)
{
    e[++top].to=v;e[top].next=prev[u];e[top].w=w;prev[u]=&e[top];
}
void dijkstra(int s)
{
    memset(dis,0x3f,sizeof(dis));
    q.push((node){s,0});dis[s]=0;
    while (!q.empty())
    {
        node t=q.top();q.pop();
        if (vis[t.x])   continue;
        for (edge *i=prev[t.x];i;i=i->next)
            if (dis[i->to]>t.dis+i->w)
            {
                dis[i->to]=t.dis+i->w;
                q.push((node){i->to,dis[i->to]});
            }
        vis[t.x]=1;
    }
}
int main()
{
    in(n);in(m);size=(n*m-n-m+1)<<1;int w;
    for (int i=1;i<m;i++)   in(w),insert(i,size+1,w),insert(size+1,i,w);
    for (int i=1;i<n-1;i++)
        for (int j=1;j<m;j++)
        {
            in(w);
            int u=(i<<1)*(m-1)+j,v=((i<<1)-1)*(m-1)+j;
            insert(u,v,w);insert(v,u,w);
        }
    for (int i=1;i<m;i++)
    {
        in(w);
        int u=0,v=((n<<1)-3)*(m-1)+i;
        insert(u,v,w);insert(v,u,w);
    }
    for (int i=0;i<n-1;i++)
        for (int j=1;j<=m;j++)
        {
            in(w);
            int u,v;
            if (j==1)   u=0,v=(i<<1)*(m-1)+m;   
            else
            if (j==m)   u=(i<<1|1)*(m-1),v=size+1;
            else    u=(i<<1)*(m-1)+j-1,v=(i<<1)*(m-1)+j+m-1;
            insert(u,v,w);insert(v,u,w);
        }
    for (int i=0;i<n-1;i++)
        for (int j=1;j<m;j++)
        {
            in(w);
            int u=(i<<1|1)*(m-1)+j,v=(i<<1)*(m-1)+j;
            insert(u,v,w);insert(v,u,w);
        }
    dijkstra(0);
    printf("%d",dis[size+1]);
}
  • 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、付费专栏及课程。

余额充值