zoukankan      html  css  js  c++  java
  • BZOJ 1001 狼抓兔子 平面图的最小割

    题目链接:

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

    题目大意:

    见链接

    思路:

    求最小割,平面图的最小割等价于对偶图的最短路

    直接建图求最短路即可,只是图比较难建。

      1 #include<bits/stdc++.h>
      2 #define IOS ios::sync_with_stdio(false);//不可再使用scanf printf
      3 #define Max(a, b) ((a) > (b) ? (a) : (b))//禁用于函数,会超时
      4 #define Min(a, b) ((a) < (b) ? (a) : (b))
      5 #define Mem(a) memset(a, 0, sizeof(a))
      6 #define Dis(x, y, x1, y1) ((x - x1) * (x - x1) + (y - y1) * (y - y1))
      7 #define MID(l, r) ((l) + ((r) - (l)) / 2)
      8 #define lson ((o)<<1)
      9 #define rson ((o)<<1|1)
     10 #pragma comment(linker, "/STACK:102400000,102400000")//栈外挂
     11 using namespace std;
     12 inline int read()
     13 {
     14     int x=0,f=1;char ch=getchar();
     15     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
     16     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     17     return x*f;
     18 }
     19 
     20 typedef long long ll;
     21 const int maxn = 6000000 + 10;
     22 const int mod = 1000000007;//const引用更快,宏定义也更快
     23 const int INF = 1e9;
     24 
     25 struct edge
     26 {
     27     int next;//指向下一个节点
     28     int u, v, w;
     29 };
     30 edge a[maxn];
     31 int head[maxn], node;//node记录节点的数目,head[i]记录连接着i的第一条边
     32 void addedge(int u, int v, int w)
     33 {
     34     a[node].u = u;
     35     a[node].v = v;
     36     a[node].w = w;
     37     a[node].next = head[u];
     38     head[u] = node++;
     39     a[node].u = v;
     40     a[node].v = u;
     41     a[node].w = w;
     42     a[node].next = head[v];
     43     head[v] = node++;
     44 }
     45 struct Heapnode
     46 {
     47     int d, u;//d为距离,u为起点
     48     Heapnode(){}
     49     Heapnode(int d, int u):d(d), u(u){}
     50     bool operator <(const Heapnode & a)const
     51     {
     52         return d > a.d;//这样优先队列先取出d小的
     53     }
     54 };
     55 ll n, m;
     56 bool v[maxn];//标记点是否加入集合
     57 int d[maxn];//起点s到各个点的最短路
     58 void init(int n)
     59 {
     60     node = 0;
     61     memset(head, -1, sizeof(head));
     62 }
     63 priority_queue<Heapnode>q;
     64 void dijkstra(ll s, ll n)//以s为起点
     65 {
     66     while(!q.empty())q.pop();
     67     for(int i = 0; i <= n; i++)d[i] = INF;
     68     d[s] = 0;
     69     memset(v, 0, sizeof(v));
     70     q.push(Heapnode(0, s));
     71     while(!q.empty())
     72     {
     73         Heapnode now = q.top();
     74         q.pop();
     75         ll u = now.u;//当前起点
     76         if(v[u])continue;//如果已经加入集合,continue
     77         v[u] = 1;
     78         for(int i = head[u]; i != -1; i = a[i].next)
     79         {
     80             edge& e = a[i];//引用节省代码
     81             if(d[e.v] > d[u] + e.w)
     82             {
     83                 d[e.v] = d[u] + e.w;
     84                 q.push(Heapnode(d[e.v], e.v));
     85             }
     86         }
     87     }
     88 }
     89 
     90 int main()
     91 {
     92     ll n, m;
     93     while(scanf("%lld%lld", &n, &m) != EOF)
     94     {
     95         if(n == 1 || m == 1)
     96         {
     97             ll ans = INF, x;
     98             for(int i = 1; i < max(n, m); i++)
     99                 scanf("%lld", &x), ans = min(ans, x);
    100             printf("%lld
    ", ans);
    101             continue;
    102         }
    103         ll x;
    104         ll t = 0, s = (n - 1) * (m - 1) * 2 + 1;
    105         init(s);
    106         ll tmp = (m - 1) * 2;//每一行的数目
    107         for(int i = 1; i <= n; i++)
    108             for(int j = 1; j < m; j++)
    109             {
    110                 scanf("%lld", &x);
    111                 if(i == 1)addedge(j * 2, t, x);
    112                 else if(i == n)addedge(s, (n - 2) * tmp + 2 * j - 1, x);
    113                 else addedge((i - 1) * tmp + 2 * j, (i - 2) * tmp + 2 * j - 1, x);
    114             }
    115         for(int i = 1; i < n; i++)
    116             for(int j = 1; j <= m; j++)
    117             {
    118                 scanf("%lld", &x);
    119                 if(j == 1)addedge(s, (i - 1) * tmp + 1, x);
    120                 else if(j == m)addedge(i * tmp, t, x);
    121                 else addedge((i - 1) * tmp + 2 * j - 2, (i - 1) * tmp + 2 * j - 1, x);
    122             }
    123         for(int i = 1; i < n; i++)
    124             for(int j = 1; j < m; j++)
    125             {
    126                 scanf("%lld", &x);
    127                 addedge((i - 1) * tmp + 2 * j - 1, (i - 1) * tmp + 2 * j, x);
    128             }
    129         dijkstra(s, s);
    130         printf("%d
    ", d[t]);
    131     }
    132     return 0;
    133 }
  • 相关阅读:
    (办公)写代码的任务完成后,编写接口文档
    (办公)eclipse连接github cannot open git-upload-pack(git-receive-pack)
    (办公)Spring boot(系列)的返回json封装类
    (办公)重新选择一个开发工具Eclipse
    (办公)项目结构
    (生活)整理电脑文件夹.
    (后台)jxl.read.biff.BiffException: Unable to recognize OLE stream
    (其他)导入密钥
    (后端)根据查询语句修改的update语句
    考研打卡_Day017
  • 原文地址:https://www.cnblogs.com/fzl194/p/9623894.html
Copyright © 2011-2022 走看看