zoukankan      html  css  js  c++  java
  • 【BZOJ1001】狼抓兔子(平面图最小割转最短路)

    题意:有一张平面图,求它的最小割。N,M.表示网格的大小,N,M均小于等于1000.

    左上角点为(1,1),右下角点为(N,M).有以下三种类型的道路 
    1:(x,y)<==>(x+1,y) 
    2:(x,y)<==>(x,y+1) 
    3:(x,y)<==>(x+1,y+1) 
     
    思路:第一眼看就是一个最小割=最大流,但点数1000000,边数6000000过大
    所以要平面图最小割转最短路 详情见周驿东《浅析最大最小定理在信息学竞赛中的应用》
    n=1和m=1要特判,链状的我也母鸡为什么会错,特判就对了
      1 var q:array[0..3100000]of longint;
      2     dis,head:array[1..2100000]of longint;
      3     inq:array[1..2100000]of boolean;
      4     vet,next,len:array[1..6100000]of longint;
      5     num:array[1..1100,1..1100,1..2]of longint;
      6     n,m,i,j,x,tot,st,ed,s,ans:longint;
      7 
      8 procedure add(a,b,c:longint);
      9 begin
     10  inc(tot);
     11  next[tot]:=head[a];
     12  vet[tot]:=b;
     13  len[tot]:=c;
     14  head[a]:=tot;
     15 end;
     16 
     17 function min(x,y:longint):longint;
     18 begin
     19  if x<y then exit(x);
     20  exit(y);
     21 end;
     22 
     23 procedure spfa;
     24 var t,w,e,v,u:longint;
     25 begin
     26  fillchar(dis,sizeof(dis),$1f);
     27  fillchar(inq,sizeof(inq),false);
     28  t:=-1; w:=0; q[0]:=st; dis[st]:=0; inq[st]:=true;
     29  while t<w do
     30  begin
     31   inc(t); u:=q[t mod (ed+1)];
     32   inq[u]:=false;
     33   e:=head[u];
     34   while e<>0 do
     35   begin
     36    v:=vet[e];
     37    if dis[u]+len[e]<dis[v] then
     38    begin
     39     dis[v]:=dis[u]+len[e];
     40     if not inq[v] then
     41     begin
     42      inc(w); q[w mod (ed+1)]:=v;
     43      inq[v]:=true;
     44     end;
     45    end;
     46    e:=next[e];
     47   end;
     48  end;
     49  writeln(dis[ed]);
     50 end;
     51 
     52 begin
     53  //assign(input,'bzoj1001.in'); reset(input);
     54  //assign(output,'bzoj1001.out'); rewrite(output);
     55  readln(n,m);
     56  if (n=1)and(m=1) then
     57  begin
     58   writeln(0);
     59   exit;
     60  end;
     61  if n=1 then
     62  begin
     63   ans:=maxlongint;
     64   for i:=1 to m-1 do begin read(x); ans:=min(ans,x); end;
     65   writeln(ans);
     66   exit;
     67  end;
     68  if m=1 then
     69  begin
     70   ans:=maxlongint;
     71   for j:=1 to n-1 do begin read(x); ans:=min(ans,x); end;
     72   writeln(ans);
     73   exit;
     74  end;
     75 
     76  for i:=1 to n do
     77   for j:=1 to m do
     78   begin
     79    inc(s); num[i,j,1]:=s;
     80    inc(s); num[i,j,2]:=s;
     81   end;
     82  inc(s);
     83  st:=s; ed:=s+1;
     84  for i:=1 to n do
     85   for j:=1 to m-1 do
     86   begin
     87    read(x);
     88    if i=1 then
     89    begin
     90     add(st,num[i,j,2],x);
     91     add(num[i,j,2],st,x);
     92    end
     93     else if i=n then
     94     begin
     95      add(ed,num[i-1,j,1],x);
     96      add(num[i-1,j,1],ed,x);
     97     end
     98      else
     99      begin
    100       add(num[i-1,j,1],num[i,j,2],x);
    101       add(num[i,j,2],num[i-1,j,1],x);
    102      end;
    103   end;
    104  for i:=1 to n-1 do
    105   for j:=1 to m do
    106   begin
    107    read(x);
    108    if j=1 then
    109    begin
    110     add(num[i,j,1],ed,x);
    111     add(ed,num[i,j,1],x);
    112    end
    113     else if j=m then
    114     begin
    115      add(num[i,j-1,2],st,x);
    116      add(st,num[i,j-1,2],x);
    117     end
    118      else
    119      begin
    120       add(num[i,j-1,2],num[i,j,1],x);
    121       add(num[i,j,1],num[i,j-1,2],x);
    122      end;
    123   end;
    124  for i:=1 to n-1 do
    125   for j:=1 to m-1 do
    126   begin
    127    read(x);
    128    add(num[i,j,1],num[i,j,2],x);
    129    add(num[i,j,2],num[i,j,1],x);
    130   end;
    131  spfa;
    132 // close(input);
    133  //close(output);
    134 end.

     UPD(2018.10.17):C++

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<string>
      4 #include<cmath>
      5 #include<iostream>
      6 #include<algorithm>
      7 #include<map>
      8 #include<set>
      9 #include<queue>
     10 #include<vector>
     11 using namespace std;
     12 typedef long long ll;
     13 typedef unsigned int uint;
     14 typedef unsigned long long ull;
     15 typedef pair<int,int> PII;
     16 typedef vector<int> VI;
     17 #define fi first
     18 #define se second
     19 #define MP make_pair
     20 #define N   2100000
     21 #define M   6100000
     22 #define eps 1e-8
     23 #define pi  acos(-1)
     24 #define oo  1e9
     25 
     26 int num[1100][1100][3],q[N],dis[N],head[N],inq[N],
     27     vet[M],nxt[M],len[M],tot,s,st,ed;
     28      
     29 int add(int a,int b,int c)
     30 {
     31     nxt[++tot]=head[a];
     32     vet[tot]=b;
     33     len[tot]=c;
     34     head[a]=tot;
     35 }
     36 
     37 void spfa(int st,int ed)
     38 {
     39     memset(dis,0x3f,sizeof(dis));
     40     memset(inq,0,sizeof(inq));
     41     int t=0; int w=1; q[1]=st; dis[st]=0; inq[st]=1;
     42     while(t<w)
     43     {
     44         t++; int u=q[t%(s+1)];
     45         inq[u]=0;
     46         int e=head[u];
     47         while(e)
     48         { 
     49             int v=vet[e];
     50             if(dis[u]+len[e]<dis[v])
     51             {
     52                 dis[v]=dis[u]+len[e];
     53                 if(!inq[v])
     54                 {
     55                     w++; q[w%(s+1)]=v; 
     56                     inq[v]=1;
     57                 }
     58             }
     59             e=nxt[e];
     60         }
     61     }
     62     printf("%d
    ",dis[ed]);
     63 }
     64     
     65 int main()
     66 {
     67     //freopen("bzoj1001.in","r",stdin);
     68     //freopen("bzoj1001.out","w",stdout);
     69     int n,m;
     70     scanf("%d%d",&n,&m);
     71     if(n==1&&m==1){printf("0
    "); return 0;}
     72     if(n==1)
     73     {
     74         int ans=oo;
     75         for(int i=1;i<m;i++) 
     76         {
     77              int x;
     78             scanf("%d",&x);
     79             ans=min(ans,x);
     80         }
     81         printf("%d
    ",ans);
     82         return 0;
     83     }
     84     if(m==1)
     85     {
     86         int ans=oo;
     87         for(int i=1;i<n;i++)
     88         {
     89             int x;
     90             scanf("%d",&x);
     91             ans=min(ans,x);
     92         }
     93         printf("%d
    ",ans);
     94         return 0;
     95     }
     96     s=0;
     97     for(int i=1;i<=n;i++)
     98      for(int j=1;j<=m;j++)
     99       for(int k=1;k<=2;k++) num[i][j][k]=++s;
    100     int st=++s;
    101     int ed=++s;
    102     for(int i=1;i<=n;i++)
    103      for(int j=1;j<=m-1;j++)
    104      {
    105          int x;
    106          scanf("%d",&x);
    107          if(i==1)
    108          {
    109              add(st,num[i][j][2],x);
    110              add(num[i][j][2],st,x);
    111          }
    112           else if(i==n)
    113           {
    114               add(ed,num[i-1][j][1],x);
    115               add(num[i-1][j][1],ed,x);
    116           }
    117            else
    118            {
    119                  add(num[i-1][j][1],num[i][j][2],x);
    120                  add(num[i][j][2],num[i-1][j][1],x);
    121            }
    122       }                                                //横边 
    123     for(int i=1;i<=n-1;i++)
    124      for(int j=1;j<=m;j++)
    125      {
    126          int x;
    127          scanf("%d",&x);
    128          if(j==1)
    129          {
    130              add(num[i][j][1],ed,x);
    131              add(ed,num[i][j][1],x);
    132          }
    133           else if(j==m)
    134           {
    135               add(num[i][j-1][2],st,x);
    136             add(st,num[i][j-1][2],x);
    137           }
    138            else 
    139            {
    140                    add(num[i][j-1][2],num[i][j][1],x);
    141                    add(num[i][j][1],num[i][j-1][2],x);
    142            }
    143      }                                                //纵边 
    144     
    145     for(int i=1;i<=n-1;i++)
    146      for(int j=1;j<=m-1;j++)
    147      {
    148          int x;
    149          scanf("%d",&x);
    150          add(num[i][j][1],num[i][j][2],x);
    151          add(num[i][j][2],num[i][j][1],x);
    152      }                                                //斜边 
    153     spfa(st,ed);
    154     return 0;
    155 }
  • 相关阅读:
    NodeJs 多核多进程并行框架实作 CNode
    Introduction to XCache ¶
    整理了一些常用的ContentType
    Node 下 Http Streaming 的跨浏览器实现
    libev 设计分析
    master + worker模式的node多核解决框架——nodecluster
    HTTP/1.1: Header Field Definitions
    HTTP/1.1 XCache header field
    XCache and XCacheLookup headers explained
    今天看了一些nodejs的文章,抱欠我又肤欠了。。。
  • 原文地址:https://www.cnblogs.com/myx12345/p/6125684.html
Copyright © 2011-2022 走看看