zoukankan      html  css  js  c++  java
  • BZOJ1001: [BeiJing2006]狼抓兔子 (最小割转最短路)

    浅析最大最小定理在信息学竞赛中的应用---周东

    ↑方法介绍
    对于一个联通的平面图G(满足欧拉公式) 在s和t间新连一条边e;
    然后建立一个原图的对偶图G*,G*中每一个点对应原图中每一个面,每一条边对应分割面的每一条边;
    那么对偶图G*中,以原图s和t间边e新划分出的面作为起点(s*),最外的面作为终点(t*);
    那么从s*到t*的每一条路都是原图G的一个割;
    下图来自上方标出百度文库网址的ppt;
    BZOJ1001: [BeiJing2006]狼抓兔子  (最小割转最短路) - 拟南芥 - 鲸头鹳
    然后用堆(优先队列)优化的迪杰斯特拉,复杂度 O((m+n)logn) n为点数,m为边数...
     
    嗯存一个堆优化迪杰斯特拉的代码...很久以前那个没有标签的一通好找..
     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<queue>
     7 using namespace std;
     8 #define pa pair<int,int>
     9 int n,m,s,t;
    10 struct node{
    11     int y;
    12     int next;
    13     int v;
    14 }e[6000100];
    15 int head[2000100]={},tot=0,dis[2000100]={};
    16 bool vis[2000100]={};
    17 priority_queue< pa, vector< pa >, greater< pa > >q;
    18 inline void init(int x,int y,int v){
    19     e[++tot].y=y;
    20     e[tot].next=head[x];
    21     e[tot].v=v;
    22     head[x]=tot;
    23 }
    24 inline int ge(int x,int y,int k){//x行,y列,在斜线的左(1)右(2);返回格子的编号
    25     return 2*(x-1)*(m-1)+2*(y-1)+k;
    26 }
    27 /*
    28 事实上如果按照从上到下从左到右来编号,在输入时的块编号是有规律的;
    29 不一定要像上面一样这样找格子编号;
    30 */
    31 void doit(){
    32     memset(dis,63,sizeof(dis));
    33     int x,y;
    34     dis[s]=0;
    35     q.push(make_pair(0,s));
    36     while(!q.empty()){
    37         x=q.top().second;
    38         q.pop();
    39         if(vis[x]){
    40             continue;
    41         }
    42         vis[x]=1;
    43         for(int i=head[x];i;i=e[i].next){
    44             y=e[i].y;
    45             if(dis[y]>dis[x]+e[i].v){
    46                 dis[y]=dis[x]+e[i].v;
    47                 vis[y]=0;
    48                 q.push(make_pair(dis[y],e[i].y));
    49             }
    50         }
    51     }
    52 }
    53 int main(){
    54     scanf("%d%d",&n,&m);
    55     int v;
    56     t=(m-1)*(n-1)*2+2;
    57     s=t-1;
    58     for(int i=1;i<=n;i++){
    59         for(int j=1;j<m;j++){
    60             scanf("%d",&v);
    61             if(i==1){
    62                 init(s,2*j,v);
    63                 init(2*j,s,v);
    64             }else if(i==n){
    65                 init(ge(n-1,j,1),t,v);
    66                 init(t,ge(n-1,j,1),v);
    67             }else{
    68                 init(ge(i-1,j,1),ge(i,j,2),v);
    69                 init(ge(i,j,2),ge(i-1,j,1),v);
    70             }
    71         }
    72     }
    73     for(int i=1;i<n;i++){
    74         for(int j=1;j<=m;j++){
    75             scanf("%d",&v);
    76             if(j==1){
    77                 init(t,ge(i,1,1),v);
    78                 init(ge(i,1,1),t,v);
    79             }else if(j==m){
    80                 init(ge(i,m-1,2),s,v);
    81                 init(s,ge(i,m-1,2),v);
    82             }else{
    83                 init(ge(i,j-1,2),ge(i,j,1),v);
    84                 init(ge(i,j,1),ge(i,j-1,2),v);
    85             }
    86         }
    87     }
    88     for(int i=1;i<n;i++){
    89         for(int j=1;j<m;j++){
    90             scanf("%d",&v);
    91             init(ge(i,j,1),ge(i,j,2),v);
    92             init(ge(i,j,2),ge(i,j,1),v);
    93         }
    94     }
    95     doit();
    96     printf("%d
    ",dis[t]);
    97     return 0;
    98 }
    View Code
  • 相关阅读:
    基础:按值传递引用类型,按引用传递引用类新 细说并沉淀
    抽象与具体
    EXTJS 零星记录 VS2008中EXTJS智能提示插件
    javascript 与 coffescript来回转换:http://js2coffee.org/
    一个冒号引发的血案
    我基本上差不多做过了coffescript所做的事
    javascript的闭包中保存的是引用与循环中事件函数处理
    用webstorm调试coffeescript
    coffeescript 下的构造函数中如何使用return语句?
    coffeescript中的forin和forof
  • 原文地址:https://www.cnblogs.com/137shoebills/p/7783842.html
Copyright © 2011-2022 走看看