zoukankan      html  css  js  c++  java
  • COGS【345】共荣圈 && 【426】血帆海盗

    题面

    UPD:COGS 貌似进不去了,链接失效就删掉了。

    如果你不小心看到了题目评论区,那你就会知道这是一道双倍经验题,另一题的链接见题目评论区……

    网络流+tarjan好题,但如果你真的的理解了网络流反向边的作用,那这就是一道大水题……

    题目要求出一定在最大流中的边的数目,显然先跑网络流(废话),然后考虑到题目要求的是一定在最大流中的边,换就话说,这条边要不可替代,什么边不可替代呢——割边(大雾)连接着两个强连通分量的边

    为什么呢?

    首先,我们要知道边满流的概念。对于正向边(并没有找到标准说法,若有知道的,评论告知),当且仅当他的流量等于容量(废话),在这道题中,就是一条匹配边(容量为一);对于反向边,当且仅当他对应的正向边流量为零,在这道题中,就是一条未匹配边的反向边。(也许和标准定义不一样,就先这么理解这道题吧)

    若一条边在某个强连通分量中,则这条边连接的两个点X—>Y一定存在一条路径Y—>X,且这条路径上的边全部都是反向边,故原图中必然存在一条路径从X—>Y,且路径上的边全部都是未匹配,即这条边不是不可替代的。

    于是,我们就可以在满流的边上跑tarjan,然后枚举每一条满流的判断即可。

      1 #include <map>
      2 #include <set>
      3 #include <cmath>
      4 #include <queue>
      5 #include <stack>
      6 #include <cstdio>
      7 #include <string>
      8 #include <vector>
      9 #include <cstring>
     10 #include <complex>
     11 #include <cstdlib>
     12 #include <iostream>
     13 #include <algorithm>
     14 #define rg register
     15 #define ll long long
     16 using namespace std;
     17 
     18 inline int gi()
     19 {
     20     rg int r = 0; rg bool b = 1; rg char c = getchar();
     21     while ((c < '0' || c > '9') && c != '-') c = getchar();
     22     if (c == '-') b = 0;
     23     while (c >= '0' && c <= '9') { r = (r << 1) + (r << 3) + c - '0', c = getchar(); }
     24     if (b) return r; return -r;
     25 }
     26 
     27 const int inf = 240002357, N = 1e5+5, M = 6e5+5;
     28 int n,m,w,S,T,Time,num,mac[N],pre[N],f[N];
     29 int stc[N],scc[N],dep[N],dfn[N],low[N];
     30 queue <int> q;
     31 struct Edge
     32 {
     33     int to,nx,cap;
     34 }eg[M];
     35 
     36 inline void add(int x,int y,int z)
     37 {
     38     eg[++num]=(Edge){y,f[x],z}; f[x]=num;
     39 }
     40 
     41 inline int dfs(int o,int flow)
     42 {
     43     if (!flow || o == T)
     44         return flow;
     45     int i,to,cap,tmp,fl;
     46     fl=0;
     47     for (i=f[o]; i; i=eg[i].nx)
     48         {
     49             to=eg[i].to, cap=eg[i].cap;
     50             if (dep[to] != dep[o]+1 || cap <= 0)
     51                 continue;
     52             tmp=dfs(to,min(flow,cap));
     53             eg[i].cap-=tmp, eg[i^1].cap+=tmp;
     54             fl+=tmp, flow-=tmp;
     55             if (!flow)
     56                 break;
     57         }
     58     if (!fl)
     59         dep[o]=0;
     60     return fl;
     61 }
     62 
     63 inline int bfs()
     64 {
     65     int i,o,to,cap;
     66     memset(dep,0,sizeof(dep));
     67     q.push(S), dep[S]=1;
     68     while (!q.empty())
     69         {
     70             o=q.front(), q.pop();
     71             for (i=f[o]; i; i=eg[i].nx)
     72                 {
     73                     to=eg[i].to, cap=eg[i].cap;
     74                     if (dep[to] || cap <= 0)
     75                         continue;
     76                     dep[to]=dep[o]+1;
     77                     if (to == T)
     78                         {
     79                             while (!q.empty()) q.pop();
     80                             break;
     81                         }
     82                     q.push(to);
     83                 }
     84         }
     85     return dep[T];
     86 }
     87 
     88 inline int dinic()
     89 {
     90     int flow;
     91     flow=0;
     92     while (bfs())
     93         flow+=dfs(S,inf);
     94     return flow;
     95 }
     96 
     97 inline void tarjan(int o)
     98 {
     99     int i,to,cap;
    100     dfn[o]=low[o]=++Time;
    101     stc[++stc[0]]=o;
    102     for (i=f[o]; i; i=eg[i].nx)
    103         {
    104             to=eg[i].to, cap=eg[i].cap;
    105             if (cap > 0)
    106                 continue;
    107             if (!dfn[to])
    108                 {
    109                     tarjan(to);
    110                     low[o]=min(low[to],low[o]);
    111                 }
    112             else if (!scc[to])
    113                 low[o]=min(low[o],dfn[to]);
    114         }
    115     if (low[o] == dfn[o])
    116         {
    117             ++scc[T+1];
    118             do
    119                 {
    120                     to=stc[stc[0]--];
    121                     scc[to]=scc[T+1];
    122                 }
    123             while (to != o);
    124         }
    125 }
    126 
    127 int main()
    128 {
    129     freopen("sphere.in","r",stdin);
    130     freopen("sphere.out","w",stdout);
    131     int i,x,y,ans,cap;
    132     n=gi(), m=gi();
    133     S=0, T=n+1, num=1, ans=0, n>>=1;
    134     for (i=1; i<=m; i++)
    135         {
    136             x=gi(), y=gi();
    137             add(x,y,1), add(y,x,0);
    138         }
    139     for (i=1; i<=n; ++i)
    140         {
    141             add(S,i,1), add(i,S,0);
    142             add(i+n,T,1), add(T,i+n,0);
    143         }
    144     w=dinic();
    145     for (i=S; i<=T; ++i)
    146         if (!dfn[i])
    147             tarjan(i);
    148     m<<=1, m++;
    149     for (i=2; i<=m; i+=2)
    150         {
    151             cap=eg[i].cap, x=eg[i].to, y=eg[i^1].to;
    152             if (cap > 0)
    153                 continue;
    154             if (scc[x] != scc[y])
    155                 ans++;
    156         }
    157     printf("%d
    ",ans);
    158     return 0;
    159 }
  • 相关阅读:
    poj 3258
    CodeForces 367E Sereja and Intervals
    Codeforces Round #240 (Div. 2) C Mashmokh and Numbers
    Codeforces Round #240 (Div. 2) D
    zoj 3768 Continuous Login
    2014/4/4做题感悟
    HDU 1878 欧拉回路
    HDU 3018 Ant Trip
    POJ 3694 Network
    Codeforces Round #239 (Div. 2)
  • 原文地址:https://www.cnblogs.com/y142857/p/7266164.html
Copyright © 2011-2022 走看看