• BZOJ 1001: [BeiJing2006]狼抓兔子(s-t平面图+最短路求最小割)


    http://www.lydsy.com/JudgeOnline/problem.php?id=1001

    题意:

    思路:
    这道题目是最小割题目,但是吧你直接套用Dinic是会超时的。

    这里有种很奇妙的做法啊,具体可以参见论文:浅析最大最小定理在信息学竞赛中的应用》--周冬

    S-T平面图:首先是一平面图(满足欧拉公式与存在对偶图),且源点S,汇点T在边界上。将S-T连线,将最外面的一个大面(无限大)一分为二了,一个为S,一个为T。然后将每条边两边的面相连,权值就是该边权值。最后跑最短路,它经过的路径就是原图中的边,最短路也就变成了最小割。

    http://blog.csdn.net/ahero_happy/article/details/6637214该博主讲得不错,可以看一下。

    一开始写了个最普通的最短路,结果超时。然后写了带队优化的,超内存了,因为用了vector来存储,最后只好改用数组来存储。

      1 /**************************************************************
      2     Problem: 1001
      3     User: Vortex
      4     Language: C++
      5     Result: Accepted
      6     Time:2112 ms
      7     Memory:89184 kb
      8 ****************************************************************/
      9  
     10 #include<iostream>
     11 #include<algorithm>
     12 #include<cstring>
     13 #include<cstdio>
     14 #include<sstream>
     15 #include<vector>
     16 #include<stack>
     17 #include<queue>
     18 #include<cmath>
     19 #include<map>
     20 #include<set>
     21 using namespace std;
     22 typedef long long ll;
     23 typedef pair<int,int> pll;
     24 const int INF = 0x3f3f3f3f;
     25 const int maxn = 1000*1000*2 + 5;
     26  
     27 int n, m;
     28 int num;
     29 int src, dst;
     30  
     31 struct Edge
     32 {
     33     int v, w;
     34     int next;
     35 }edge[3*maxn];
     36  
     37 struct HeapNode
     38 {
     39     int d, u;
     40     HeapNode(int x, int y) :d(x), u(y){}
     41     bool operator < (const HeapNode& rhs) const{
     42         return d > rhs.d;
     43     }
     44 };
     45  
     46 int head[maxn];
     47 bool done[maxn];
     48 int d[maxn];
     49  
     50 void AddEdges(int u, int v, int w)
     51 {
     52     edge[num].v=v ;edge[num].w=w ;
     53     edge[num].next=head[u] ;head[u]=num++ ;
     54 }
     55  
     56 void dijkstra(int s)
     57 {
     58     priority_queue<HeapNode> Q;
     59     for (int i = 0; i <=dst; i++)    d[i] = INF;
     60     d[s] = 0;
     61     memset(done, 0, sizeof(done));
     62     Q.push(HeapNode(0,s));
     63     while (!Q.empty())
     64     {
     65         HeapNode x = Q.top(); Q.pop();
     66         int u = x.u;
     67         if (done[u]) continue;
     68         done[u] = true;
     69         for (int i = head[u]; i!=-1; i=edge[i].next)
     70         {
     71             if (d[edge[i].v] > d[u] + edge[i].w)
     72             {
     73                 d[edge[i].v] = d[u] + edge[i].w;
     74                 Q.push(HeapNode(d[edge[i].v],edge[i].v));
     75             }
     76         }
     77     }
     78 }
     79  
     80 int main()
     81 {
     82     //freopen("in.txt","r",stdin);
     83     while(~scanf("%d%d",&n,&m))
     84     {
     85         src=0,dst=2*(n-1)*(m-1)+1;
     86  
     87         memset(head,-1,sizeof(head));
     88         num=0;
     89  
     90         for(int i=1;i<=n;i++)
     91         {
     92             for(int j=1;j<m;j++)
     93             {
     94                 int u,v,w;
     95                 scanf("%d",&w);
     96                 if(i==1)  u=src;
     97                 else u=(2*(i-1)-1)*(m-1)+j;
     98                 if(i==n)  v=dst;
     99                 else v=(2*(i-1))*(m-1)+j;
    100                 AddEdges(u,v,w);
    101                 AddEdges(v,u,w);
    102             }
    103         }
    104  
    105         for(int i=1;i<n;i++)
    106         {
    107             for(int j=1;j<=m;j++)
    108             {
    109                 int u,v,w;
    110                 scanf("%d",&w);
    111                 if(j==1)  u=dst;
    112                 else u=(2*(i-1))*(m-1)+j-1;
    113                 if(j==m)  v=src;
    114                 else v=(2*(i-1))*(m-1)+j-1+m;
    115                 AddEdges(u,v,w);
    116                 AddEdges(v,u,w);
    117             }
    118         }
    119  
    120         for(int i=1;i<n;i++)
    121         {
    122             for(int j=1;j<m;j++)
    123             {
    124                 int u,v,w;
    125                 scanf("%d",&w);
    126                 u=(2*(i-1))*(m-1)+j;
    127                 v=(2*(i-1)+1)*(m-1)+j;
    128                 AddEdges(u,v,w);
    129                 AddEdges(v,u,w);
    130             }
    131         }
    132  
    133         dijkstra(src);
    134         printf("%d
    ",d[dst]);
    135     }
    136     return 0;
    137 }
  • 相关阅读:
    (转)使用vsphere client 克隆虚拟机
    【转】VIM高级用法笔记
    Oracle RAC的Failover
    /dev/shm过小导致ORA00845错误解决方法
    (转)How to use udev for Oracle ASM in Oracle Linux 6
    ORACLE十进制与十六进制的转换
    解决Oracle RAC不能自动启动的问题
    RAC集群时间同步服务
    db link hang的解决方法
    【转载】Oracle数据恢复 Linux / Unix 误删除的文件恢复
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7265931.html
Copyright © 2020-2023  润新知