zoukankan      html  css  js  c++  java
  • POJ 1966 <点连通度>

    题意:

    给出点和边的个数n, m

    给出相连点的边..形如(a, b)

    求最少删去多少个点可以使存在不相邻的两个点不连通..

    思路:

    拆点+求最大流..

    ①. 构造一个容量网络N

    ②. 原图中的每个顶点变成网络N中的两个顶点v' 和 v'', 顶点v' 和 v''之间存在一条弧容量为1<确保这个点只可以路过一次..>

    ③. 原图G中的每条边e(u, v), 在N中都有对应弧为e'<u'', v'> 和 e''<u', v''>, e' 和 e'' 容量为INF<表示可以在任意两个点之间连线>

    ④. 遍历两两不相邻的点求最大流的最小值..

    Tips:

    ※. 用EK算法可以在POJ上ac~但是学校OJ就会wa..因为POJ只要固定一个点就好~而学校的需要遍历两两不相邻的点..感觉是POJ的数据弱了..

    ※. 最大流用SAP算法能快点..

    ※. 源点为u'' 汇点为v'

    Code:

    POJ ac代码
     1 #include <stdio.h>
     2 #include <cstring>
     3 #include <queue>
     4 #define INF 0x1f1f1f1f
     5 #define clr(x) memset(x, 0, sizeof(x))
     6 using namespace std;
     7 
     8 int cap[155][155], flow[155][155];
     9 int p[155], a[155];
    10 int f, n, m;
    11 
    12 void EK(int s, int t)
    13 {
    14     queue<int> q;
    15     memset(flow, 0, sizeof(flow));
    16     memset(a, 0, sizeof(a));
    17     memset(p, 0, sizeof(p));
    18     f = 0;
    19     while(1)
    20     {
    21         memset(a, 0, sizeof(a));
    22         a[s] = INF;
    23         q.push(s);
    24         while(!q.empty())
    25         {
    26             int u = q.front();
    27             q.pop();
    28             for(int v = 1; v <= 2*n; ++v)
    29             if(!a[v] && cap[u][v] > flow[u][v])
    30             {
    31                 p[v] = u;
    32                 q.push(v);
    33                 a[v] = a[u] < cap[u][v] - flow[u][v]? a[u]:cap[u][v] - flow[u][v];
    34             }
    35         }
    36         if(a[t] == 0) break;
    37         for(int u = t; u != s; u = p[u])
    38         {
    39             flow[p[u]][u] += a[t];
    40             flow[u][p[u]] -= a[t];
    41         }
    42         f += a[t];
    43     }
    44 }
    45 
    46 int main()
    47 {
    48     int i, j, k;
    49     int a, b;
    50     while(scanf("%d %d", &n, &m) != EOF)
    51     {
    52         if(n == 0){
    53             puts("0");
    54             continue;
    55         }
    56         clr(cap);
    57 
    58         for(i = 1; i <= n; ++i)
    59         cap[i][i+n] = 1;
    60 
    61         while(m--){
    62             scanf(" (%d,%d)", &a, &b);
    63             cap[a+1+n][b+1] = cap[b+1+n][a+1] = INF;
    64         }
    65         int ans = INF;
    66 
    67         for(i = 2; i <= n; ++i){
    68             EK(n+1, i);
    69             if(f < ans) ans = f;
    70         }
    71 
    72         if(ans == INF)
    73             printf("%d\n", n);
    74         else
    75             printf("%d\n", ans);
    76     }
    77 
    78     return 0;
    79 }

     

  • 相关阅读:
    火狐插件火狐黑客插件将Firefox变成黑客工具的七个插件
    memcache安装环境:WINDOWS 7
    PHP正则表达式
    968. 监控二叉树 力扣(困难) dfs 官方说DP
    375. 猜数字大小 II 力扣(中等) 区间动态规划、记忆化搜索
    629. K个逆序对数组 力扣(困难) 区间动态规划
    剑指 Offer 51. 数组中的逆序对 力扣(困难) 巧用归并排序算法
    488. 祖玛游戏 力扣(困难) dfs
    16. 最接近的三数之和 力扣(中等) 双指针
    319. 灯泡开关 力扣(中等) 数论
  • 原文地址:https://www.cnblogs.com/Griselda/p/2657268.html
Copyright © 2011-2022 走看看