• P1345 [USACO5.4]奶牛的电信Telecowmunication【最小割】【最大流】


    题目描述

    农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流。这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相连,a2与a3相连,等等,那么电脑a1和a(c)就可以互发电邮。

    很不幸,有时候奶牛会不小心踩到电脑上,农夫约翰的车也可能碾过电脑,这台倒霉的电脑就会坏掉。这意味着这台电脑不能再发送电邮了,于是与这台电脑相关的连接也就不可用了。

    有两头奶牛就想:如果我们两个不能互发电邮,至少需要坏掉多少台电脑呢?请编写一个程序为她们计算这个最小值。

    以如下网络为例:

    1* / 3 - 2*

    这张图画的是有2条连接的3台电脑。我们想要在电脑1和2之间传送信息。电脑1与3、2与3直接连通。如果电脑3坏了,电脑1与2便不能互发信息了。

    输入格式

    第一行 四个由空格分隔的整数:N,M,c1,c2.N是电脑总数(1<=N<=100),电脑由1到N编号。M是电脑之间连接的总数(1<=M<=600)。最后的两个整数c1和c2是上述两头奶牛使用的电脑编号。连接没有重复且均为双向的(即如果c1与c2相连,那么c2与c1也相连)。两台电脑之间至多有一条连接。电脑c1和c2不会直接相连。

    第2到M+1行 接下来的M行中,每行包含两台直接相连的电脑的编号。

    输出格式

    一个整数表示使电脑c1和c2不能互相通信需要坏掉的电脑数目的最小值。

    输入输出样例

    输入 #1
    3 2 1 2
    1 3
    2 3
    输出 #1
    1


    思路
      肯定是最小割,直接交不要怂
      观察一下,这是蓝题,不会有这样的送分题的。
      再观察一下,发现踩烂的是电脑。
      所以就变成了求最小割点。不是tarjan
      最小割点的求法: 把每个点拆成流入流出两个点, 中间连一条费用为 1 的边,这条边被破坏即这个点被破坏。
      点与点之间理所应当连inf的容量,保证不会把连线给拆了。
    CODE

      
      1 #include <bits/stdc++.h>
      2 #define dbg(x) cout << #x << "=" << x << endl
      3 #define eps 1e-8
      4 #define pi acos(-1.0)
      5 
      6 using namespace std;
      7 typedef long long LL;
      8 
      9 template<class T>inline void read(T &res)
     10 {
     11     char c;T flag=1;
     12     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
     13     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
     14 }
     15 
     16 namespace _buff {
     17     const size_t BUFF = 1 << 19;
     18     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
     19     char getc() {
     20         if (ib == ie) {
     21             ib = ibuf;
     22             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
     23         }
     24         return ib == ie ? -1 : *ib++;
     25     }
     26 }
     27 
     28 int qread() {
     29     using namespace _buff;
     30     int ret = 0;
     31     bool pos = true;
     32     char c = getc();
     33     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
     34         assert(~c);
     35     }
     36     if (c == '-') {
     37         pos = false;
     38         c = getc();
     39     }
     40     for (; c >= '0' && c <= '9'; c = getc()) {
     41         ret = (ret << 3) + (ret << 1) + (c ^ 48);
     42     }
     43     return pos ? ret : -ret;
     44 }
     45 
     46 const int maxn = 1e4 + 7;
     47 const int inf = 0x3f3f3f3f;
     48 
     49 int n,m,cnt = 1,s,t;
     50 
     51 int maxflow;
     52 int head[maxn];
     53 
     54 struct Node {
     55     int v,dis,nxt;
     56 }edge[maxn << 2];
     57 
     58 void BuildGraph(int u,int v,int dis){
     59     edge[++cnt].nxt = head[u];
     60     edge[cnt].v = v;
     61     edge[cnt].dis = dis;
     62     head[u] = cnt;
     63 
     64     edge[++cnt].nxt = head[v];
     65     edge[cnt].v = u;
     66     edge[cnt].dis = 0;
     67     head[v] = cnt;
     68 }
     69 
     70 int depth[maxn];
     71 
     72 bool bfs() {
     73     queue<int> q;
     74     while(!q.empty())
     75         q.pop();
     76     memset(depth,0,sizeof(depth));
     77     depth[s] = 1;
     78     q.push(s);
     79     while(!q.empty()){
     80         int u = q.front();
     81         q.pop();
     82         for(int i = head[u]; i; i = edge[i].nxt){
     83             int v = edge[i].v;
     84             if(edge[i].dis && !depth[v]){
     85                 depth[v] = depth[u] + 1;
     86                 if(v == t)
     87                     return true;
     88                 q.push(v);
     89             }
     90         }
     91     }
     92     return false;
     93 }
     94 
     95 int Dinic(int u,int flow) {//最大流
     96     if(u == t)
     97         return flow;
     98     int rest = flow,temp;//残量网络
     99     for(int i = head[u];i;i = edge[i].nxt) {
    100         int v = edge[i].v;
    101         if(depth[v] == depth[u] + 1 && edge[i].dis){
    102             temp = Dinic(v,min(rest,edge[i].dis));
    103             if(!temp)depth[v] = 0;
    104             rest -= temp;
    105             edge[i].dis -= temp;
    106             edge[i ^ 1].dis += temp;
    107         }
    108     }
    109     return flow - rest;
    110 }
    111 
    112 int main(){
    113     scanf("%d %d %d %d",&n, &m, &s, &t);
    114     for(int i = 1;i <= n;i++){
    115         BuildGraph(i, i + n, 1);
    116     }
    117 
    118     int u,v;
    119     for(int i = 1; i <= m; i++){
    120         scanf("%d %d",&u, &v);
    121         BuildGraph(u + n,v,inf);
    122         BuildGraph(v + n,u,inf);
    123     }
    124     s += n;
    125     int flow = 0;
    126     while(bfs()){
    127         while(flow = Dinic(s,inf))
    128             maxflow += flow;
    129     }
    130     printf("%d
    ",maxflow);
    131     return 0;
    132 }
    View Code
  • 相关阅读:
    scala中 object 和 class的区别
    scala中的apply方法与unapply方法
    Scala中的样例类详解
    Scala 中下划线的一些魔法
    Hadoop搭建配置参数调优
    设置ESX/ESXi中(Linux)虚拟机从U盘引导启动
    CentOS下编译安装Busybox
    LRU算法简单实现
    Spark 3.0 动态分区裁剪(Dynamic Partition Pruning)
    Hive中的数据分桶以及使用场景
  • 原文地址:https://www.cnblogs.com/orangeko/p/12359769.html
Copyright © 2020-2023  润新知