• poj 1966(无向图点连通度 )


    无向图点连通度:

    构造有向图,再枚举源汇点求最小割。

    1、无向图中任一个点u拆边为u和u+N,连容量为1的有向边。

    2、对于无向图中原有的任意无向边(u,v),在构造的有向图中添加边(u+N,v)和(v+N,v),容量均为无穷。(拆边规则)

    3、O(n^2)枚举源点(拆后出点)、汇点(拆后入点)求最小割的最小值(注意源点与汇点直接相连的情况,显然此时最大流流出来的是inf)。

    View Code
      1 // File Name: 1966.cpp
      2 // Author: Missa
      3 // Created Time: 2013/4/19 星期五 10:29:17
      4 
      5 #include<iostream>
      6 #include<cstdio>
      7 #include<cstring>
      8 #include<algorithm>
      9 #include<cmath>
     10 #include<queue>
     11 #include<stack>
     12 #include<string>
     13 #include<vector>
     14 #include<cstdlib>
     15 #include<map>
     16 #include<set>
     17 using namespace std;
     18 #define CL(x,v) memset(x,v,sizeof(x));
     19 #define R(i,st,en) for(int i=st;i<en;++i)
     20 #define LL long long
     21 
     22 const int inf = 0x3f3f3f3f;
     23 const int maxn = 105;
     24 const int maxm = 10010;
     25 struct Edge
     26 {
     27     int v, c, next;//指向点,流量,下一个点
     28 }p[maxm << 1];
     29 int head[maxn], e;
     30 int d[maxn], cur[maxn];//层次记录,当前弧优化
     31 int n, m, st, en;
     32 void init()
     33 {
     34     e = 0;
     35     memset(head, -1, sizeof(head));
     36 }
     37 void addEdge(int u, int v, int c)
     38 {
     39     p[e].v = v; p[e].c = c; 
     40     p[e].next = head[u];head[u] = e++;
     41     p[e].v = u; p[e].c = 0; //无向图时逆边赋值流量cap,有向图时赋值0.
     42     p[e].next = head[v];head[v] = e++;
     43 }
     44 int bfs(int st, int en)
     45 {
     46     queue <int> q;
     47     memset(d, 0, sizeof(d));
     48     d[st] = 1;
     49     q.push(st);
     50     while (!q.empty())
     51     {
     52         int u = q.front(); q.pop();
     53         for (int i = head[u]; i != -1; i = p[i].next)
     54         {
     55             if (p[i].c > 0 && !d[p[i].v])
     56             {
     57                 d[p[i].v] = d[u] + 1;
     58                 q.push(p[i].v);
     59             }
     60         }
     61     }
     62     return d[en];
     63 }
     64 int dfs(int u, int a)//a表示流量
     65 {
     66     if (u == en || a == 0) return a;
     67     int f, flow = 0;
     68     for (int& i = cur[u]; i != -1; i = p[i].next)
     69     {
     70         if (d[u] + 1 == d[p[i].v] && (f = dfs(p[i].v,min(a,p[i].c))) > 0)
     71         {
     72             p[i].c -= f;
     73             p[i^1].c += f;
     74             flow += f;
     75             a -= f;
     76             if (!a) break;
     77         }
     78     }
     79     return flow;
     80 }
     81 int dinic(int st, int en, int tmp)
     82 {
     83     int res = 0;
     84     while (bfs(st, en))
     85     {
     86         for (int i = 0; i <= n; ++i)
     87             cur[i] = head[i];
     88         res += dfs(st, inf);
     89         if (res > tmp) return res;
     90     }
     91     return res;
     92 }
     93 int N;
     94 struct Node
     95 {
     96     int u, v;
     97 }edg[maxm];
     98 void build(int u, int v)
     99 {
    100     init();
    101     n = N << 1;
    102     st = u + N, en = v;
    103     for (int i = 1; i <= N; ++i)
    104         addEdge(i, i +N, 1);
    105     for (int i = 0; i < m; ++i)
    106     {
    107         addEdge(edg[i].u + N, edg[i].v, inf);
    108         addEdge(edg[i].v + N, edg[i].u, inf);
    109     }
    110 }
    111 
    112 int main()
    113 {
    114     while(~scanf("%d%d",&N,&m))
    115     {
    116         for (int i = 0; i < m; ++i)
    117         {
    118             scanf(" (%d,%d)", &edg[i].u, &edg[i].v);
    119             edg[i].u++;
    120             edg[i].v++;
    121         }
    122         int ans = inf;
    123         for (int i = 1; i <= N; ++i)
    124             for (int j = 1; j <= N; ++j)
    125             {
    126                 if ( i == j) continue;
    127                 build(i, j);
    128                 int tmp = dinic(st, en, ans);
    129                 if ( tmp < ans)
    130                     ans = tmp;
    131             }
    132         if (ans == inf) ans = N;
    133         printf("%d\n",ans);
    134     }
    135     return 0;
    136 }
  • 相关阅读:
    二叉树中序遍历 2021.4.14
    简单题 好数对题目 2021.4.13
    2021.4.3 在排序数组中查找元素的第一个和最后一个位置
    力扣刷题记录2021.4.13 最富有客户的资产总量
    iOS开源项目阅读整理
    Missing iOS Distribution signing identity解决方案
    微信票选项目遇到的坑
    [转]从此爱上iOS Autolayout
    [转]iOS应用性能调优的25个建议和技巧
    iOS中用json接收图片的二进制流
  • 原文地址:https://www.cnblogs.com/Missa/p/3030336.html
Copyright © 2020-2023  润新知