【BZOJ】1001 狼抓兔子


【参考】

本题的题解:
http://www.cnblogs.com/zhj5chengfeng/p/3273531.html

还有那篇平面图网络流的论文:
《两极相通——浅析最大—最小定理在信息学竞赛中的应用》

两篇足够了。


【代码】

#pragma comment<linker,"/STACK:102400000">

#include <cstdio>
#include <cstring>
#include <cctype>
#include <queue>
using namespace std;

#define mp(i,j) make_pair(i,j)
#define fs first
#define sc second

typedef pair<int,int> PairInt;

const int S=2000000;
const int M=6000000;

int n,m;
int sc,sk;
struct Graph
{
    int v,d,nxt;
}mp[M];
int tt,hd[S];

inline int read(void)
{
    int x=0,f=1; char c=getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}

inline void ins(int u,int v,int d)
{
    mp[++tt].v=v;
    mp[tt].d=d;
    mp[tt].nxt=hd[u];
    hd[u]=tt;
}

inline int id(int i,int j,int kd)
{
    return ((i-1)*(m-1)+j-1)*2+kd;
}

priority_queue<PairInt> q;
int vis[S],dis[S];

int main(void)
{   
    n=read(),m=read();
    if (n<=1&&m<=1) {printf("0\n");return 0;}

    int x;
    sc=0,sk=(n-1)*(m-1)<<1|1;    //from 0 to vtx
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m-1;j++)
        {
            x=read();
            if (i==1) 
                ins(sc,id(i,j,1),x),ins(id(i,j,1),sc,x);
            else
            if (i==n)
                ins(id(i-1,j,2),sk,x),ins(sk,id(i-1,j,2),x);
            else ins(id(i-1,j,2),id(i,j,1),x),ins(id(i,j,1),id(i-1,j,2),x);
        }
    for (int i=1;i<=n-1;i++)
        for (int j=1;j<=m;j++)
        {
            x=read();
            if (j==1&&j==m)
                ins(sc,sk,x),ins(sk,sc,x);
            else
            if (j==1)
                ins(id(i,j,2),sk,x),ins(sk,id(i,j,2),x);
            else
            if (j==m)
                ins(sc,id(i,j-1,1),x),ins(id(i,j-1,1),sc,x);
            else ins(id(i,j-1,1),id(i,j,2),x),ins(id(i,j,2),id(i,j-1,1),x);
        }
    for (int i=1;i<=n-1;i++)
        for (int j=1;j<=m-1;j++)
        {
            x=read();
            ins(id(i,j,1),id(i,j,2),x),ins(id(i,j,2),id(i,j,1),x);
        }

    PairInt now;
    memset(vis,0,sizeof vis);
    memset(dis,63,sizeof dis);
    q.push(mp(0,sc));
    for (;!vis[sk];)
    {
        now=q.top(),q.pop();
        if (vis[now.sc]==1) continue;
        dis[now.sc]=-now.fs,vis[now.sc]=1;
        for (int k=hd[now.sc];k;k=mp[k].nxt)
            if (!vis[mp[k].v]&&dis[now.sc]+mp[k].d<dis[mp[k].v])
                q.push(mp(now.fs-mp[k].d,mp[k].v));
    }
    printf("%d\n",dis[sk]);

    return 0;
}

【小结】

主要补充的就是这一部分,总结一下平面图网络流的一些要点。

①如何想到用最短路的方法解网络流?
很直接的就能想到,平面图结构统一利于编号的网络。

②如何编号才能降低出错率?
一般来说,平面图网络流的每一块区域都是矩形的吧。
那就弄个函数 id(i,j) 表示第 i 行,第j列的那个区域的编号。
然后注意边权与区域的关系。
这个应该不要紧,毕竟我们还可以调试。

③特别注意小数据的特判,特判主要有两个地方要注意:
- 在跑最短路时把特殊情况处理掉;
- 区域连边时若只有 1 行,那么会出现s连到 t <script type="math/tex" id="MathJax-Element-250">t</script>的情况。

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、付费专栏及课程。

余额充值