zoukankan      html  css  js  c++  java
  • BZOJ 1001: [BeiJing2006]狼抓兔子(最短路)

    平面图的最小割转化为对偶图的最短路(资料:两极相通——浅析最大最小定理在信息学竞赛中的应用) ,然后DIJKSTRA就OK了.

    -------------------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<iostream>
     
    #define rep(i,n) for(int i=0;i<n;++i)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define Rep(i,l,r) for(int i=l;i<r;++i)
    #define memory(x) cout<<sizeof(x)/(1024*1024.0)<<"MB"
     
    using namespace std;
     
    const int maxn=1996005;
    const int inf=0x3f3f3f3f;
     
    struct DIJKSTRA {
    struct Edge {
    int u,v,d;
    Edge(int u,int v,int d):u(u),v(v),d(d) {}
    };
    struct node {
    int u,d;
    bool operator < (const node &o) const {
    return d>o.d;
    }
    };
    int n,s,t;
    int d[maxn];
    vector<int> g[maxn];
    vector<Edge> edges;
    void init(int n) {
    this->n=n;
    rep(i,n) g[i].clear();
    edges.clear();
    }
    void addEdge(int u,int v,int d) {
    edges.push_back( (Edge) {u,v,d} );
    g[u].push_back(edges.size()-1);
    g[v].push_back(edges.size()-1);
    }
    int Dijkstra(int s,int t) {
    this->s=s; this->t=t;
    clr(d,inf); d[s]=0;
    priority_queue<node> q;
    q.push( (node) {s,0} );
    while(!q.empty()) {
    node x=q.top(); q.pop();
    if(x.d!=d[x.u]) continue;
    rep(i,g[x.u].size()) {
    Edge &e=edges[g[x.u][i]];
    int u=e.u,v=e.v;
    if(v==x.u) swap(u,v);
    if(d[v]>d[u]+e.d) {
    d[v]=d[u]+e.d;
    q.push( (node) {v,d[v]} );
    }
    }
    }
    return d[t];
    }
    } dijkstra;
    int main()
    {
    // freopen("test.in","r",stdin);
    // freopen("test.out","w",stdout);
    int n,m,d;
    scanf("%d%d",&n,&m);
    int _n=(n-1)*(m-1)*2+1;
    dijkstra.init(_n+1);
    rep(i,n)
    Rep(j,1,m) {
    scanf("%d",&d);
    int x=2*(m-1)*i+j*2;
    if(!i) dijkstra.addEdge(_n,j*2,d);
    else if(i==n-1) dijkstra.addEdge(0,x-2*(m-1)-1,d);
        else dijkstra.addEdge(x,x-1-2*(m-1),d);
    }
    rep(i,n-1)
       Rep(j,1,m+1) {
        scanf("%d",&d);
        int x=2*i*(m-1)+j*2-1;
        if(j==1) dijkstra.addEdge(0,x,d);
        else if(j==m) dijkstra.addEdge(_n,x-1,d);
            else dijkstra.addEdge(x,x-1,d);
       }
    rep(i,n-1)
       Rep(j,1,m) {
        scanf("%d",&d);
        int x=i*(m-1)*2+j*2;
        dijkstra.addEdge(x,x-1,d);
       }
    printf("%d ",dijkstra.Dijkstra(0,_n));
    return 0;
    }

      

    ------------------------------------------------------------------------------- 

    001: [BeiJing2006]狼抓兔子

    Time Limit: 15 Sec  Memory Limit: 162 MB
    Submit: 11789  Solved: 2752
    [Submit][Status][Discuss]

    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
  • 相关阅读:
    如何使用命令行备份SAP HANA数据库
    Rootkit介绍
    web渗透测试基本步骤
    IIS服务器的安全保护措施
    渗透测试的流程
    Kali Linux之常见后门工具介绍
    中间人攻击(MITM)之数据截获原理
    口令破解工具
    常见渗透测试工具集成系统简介
    Kali Linux之使用SET快捷生成钓鱼网站方法
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4374223.html
Copyright © 2011-2022 走看看