zoukankan      html  css  js  c++  java
  • bzoj 1001 [BeiJing2006]狼抓兔子

    平面图最小割转对偶图最短路。

    初看是一个裸的最小割,但数据范围1000000个点……

    在原平面图上加入一条S到T的边,形成一个新区域。

    将图上每个区域(二维)看做一个点(包括新区域和无限大的区域),区域边界看做边,边权为边界所对应原图中的边的边权,新建图。

    删掉新区域和无限大区域之间的边。

    此时原图最小割等于新图上新区域点到无限大区域点的最短路。

    直观理解一下感觉挺对。

    至于怎么实现上面的步骤,本题很简单随便搞一搞就行了,一般平面图的话就不(gen)再(ben)赘(bu)述(hui)了。

    最后注意1*m和n*1的情况,此时根本没有区域,要特判。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<queue>
      6 using namespace std;
      7 const int dian=2000005;
      8 const int bian=8000005;
      9 struct nd{
     10     int bh;
     11     int diss;
     12     bool operator < (const nd &rhs)const{
     13         return rhs.diss<diss;
     14     }
     15 };
     16 int h[dian],nxt[bian],ver[bian],val[bian],dis[dian],v[dian];
     17 int n,m,tot,aa;
     18 int S,T;
     19 void add(int a,int b,int c){
     20     tot++;ver[tot]=b;val[tot]=c;nxt[tot]=h[a];h[a]=tot;
     21 }
     22 void dijkstra(){
     23     memset(dis,0x3f,sizeof(dis));
     24     memset(v,0,sizeof(v));
     25     priority_queue<nd>q;
     26     dis[S]=0;
     27     nd hhd;
     28     hhd.bh=S;
     29     hhd.diss=0;
     30     q.push(hhd);
     31     while(!q.empty()){
     32         hhd=q.top();
     33         q.pop();
     34         int x=hhd.bh;
     35         if(v[x])
     36             continue;
     37         v[x]=1;
     38         for(int i=h[x];i;i=nxt[i]){
     39             int y=ver[i];
     40             if(dis[y]>dis[x]+val[i]){
     41                 dis[y]=dis[x]+val[i];
     42                 hhd.bh=y;
     43                 hhd.diss=dis[y];
     44                 q.push(hhd);
     45             }
     46         }
     47     }
     48 }
     49 int main(){
     50     memset(h,0,sizeof(h));
     51     memset(nxt,0,sizeof(nxt));
     52     tot=0;
     53     scanf("%d%d",&n,&m);
     54     if(n==1){
     55         int la=0x3f3f3f3f;
     56         for(int i=1;i<m;i++){
     57             scanf("%d",&aa);
     58             la=min(la,aa);
     59         }
     60         printf("%d",la);
     61         return 0;
     62     }
     63     if(m==1){
     64         int la=0x3f3f3f3f;
     65         for(int i=1;i<n;i++){
     66             scanf("%d",&aa);
     67             la=min(la,aa);
     68         }
     69         printf("%d",la);
     70         return 0;
     71     }
     72     S=n*m*2+1,T=n*m*2+2;
     73     for(int i=1;i<m;i++){
     74         scanf("%d",&aa);
     75         add(S,i,aa);
     76         add(i,S,aa);
     77     }
     78     for(int i=2;i<n;i++)
     79         for(int j=1;j<m;j++){
     80             scanf("%d",&aa);
     81             add(n*m+(i-2)*m+j,(i-1)*m+j,aa);
     82             add((i-1)*m+j,n*m+(i-2)*m+j,aa);
     83         }
     84     for(int i=1;i<m;i++){
     85         scanf("%d",&aa);
     86         add(n*m+(n-2)*m+i,T,aa);
     87         add(T,n*m+(n-2)*m+i,aa);
     88     }
     89     for(int i=1;i<n;i++)
     90         for(int j=1;j<=m;j++){
     91             scanf("%d",&aa);
     92             if(j==1){
     93                 add(T,n*m+(i-1)*m+j,aa);
     94                 add(n*m+(i-1)*m+j,T,aa);
     95             }
     96             else if(j==m){
     97                 add((i-1)*m+j-1,S,aa);
     98                 add(S,(i-1)*m+j-1,aa);
     99             }
    100             else{
    101                 add((i-1)*m+j-1,n*m+(i-1)*m+j,aa);
    102                 add(n*m+(i-1)*m+j,(i-1)*m+j-1,aa);
    103             }
    104         }
    105     for(int i=1;i<n;i++)
    106         for(int j=1;j<m;j++){
    107             scanf("%d",&aa);
    108             add(n*m+(i-1)*m+j,(i-1)*m+j,aa);
    109             add((i-1)*m+j,n*m+(i-1)*m+j,aa);
    110         }
    111     dijkstra();
    112     printf("%d",dis[T]);
    113     return 0;
    114 }
  • 相关阅读:
    osip2 代码分析
    批处理命令——call 和 start
    在VS2010 VC++项目中引用Lib静态库(以Openssl为例)
    Gerrit 代码审核服务器的工作流和原理
    crucible VS gerrit
    领导者/追随者(Leader/Followers)模型和半同步/半异步(half-sync/half-async)模型都是常用的客户-服务器编程模型
    半同步半异步I/O的设计模式(half sync/half async)
    高并发系统设计
    通过Nginx反向代理之后客户端验证码session不一致造成无法验证通过的问题解决
    使用Nodpad++正则替换
  • 原文地址:https://www.cnblogs.com/dugudashen/p/6257225.html
Copyright © 2011-2022 走看看