zoukankan      html  css  js  c++  java
  • bzoj 1797: [Ahoi2009]Mincut 最小割

    求最小割的可行边与必须边,先求一遍最大流,然后在残量网络上求强连通分量,对于可行边 起始点与结束点要在不同的强连通分量里,对于必须边 起始点要与S在一个SCC里 结束点要与T在一个SCC里。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<cmath>
      6 #include<queue>
      7 #include<algorithm>
      8 #include<vector>
      9 #define M 1000009
     10 #define EPS 1e-10
     11 #define MO 10000
     12 #define ll long long
     13 using namespace std;
     14 ll read()
     15 {
     16     char ch=getchar();
     17     ll x=0,f=1;
     18     for(;ch<'0'||ch>'9';ch=getchar())
     19         if(ch=='-')
     20           f=-1;
     21     for(;ch>='0'&&ch<='9';ch=getchar())
     22         x=x*10+ch-'0';
     23     return x*f;
     24 }
     25 int dfn[M],low[M],T1,belong[M],sum,t,q[M],n,m,S,T,head[M],next[M],u[M],v[M],cnt=1,d[M],f[M],fr[M];
     26 void jia(int a1,int a2,int a3)
     27 {
     28   cnt++;
     29   fr[cnt]=a1;
     30   next[cnt]=head[a1];
     31   head[a1]=cnt;
     32   u[cnt]=a2;
     33   v[cnt]=a3;
     34 }
     35 bool bfs()
     36 {
     37   memset(d,0,sizeof(int)*(n+1));
     38   d[S]=1;
     39   q[1]=S;
     40   int h=0,t=1;
     41   for(;h<t;)
     42     {
     43       int p=q[++h];
     44       for(int i=head[p];i;i=next[i])
     45         if(v[i]&&!d[u[i]])
     46           {
     47             d[u[i]]=d[p]+1;
     48             if(u[i]==T)
     49               return 1;
     50             q[++t]=u[i];
     51           }
     52     }
     53    return 0;
     54 }
     55 int dinic(int x,int f)
     56 {
     57   if(x==T)
     58     return f;
     59   int rest=f;
     60   for(int i=head[x];i&&rest;i=next[i])
     61     if(v[i]&&d[u[i]]==d[x]+1)
     62       {
     63         int now=dinic(u[i],min(rest,v[i]));
     64         if(!now)
     65           d[u[i]]=0;
     66         rest-=now;
     67         v[i]-=now;
     68         v[i^1]+=now;
     69       }
     70   return f-rest;
     71 }
     72 void tarjin(int x)
     73 {
     74   dfn[x]=low[x]=++T1;
     75   q[++t]=x;
     76   f[x]=1;
     77   for(int i=head[x];i;i=next[i])
     78     if(v[i])
     79       {
     80         if(!dfn[u[i]])
     81           {
     82             tarjin(u[i]);
     83             low[x]=min(low[x],low[u[i]]);
     84           }
     85         else  if(f[u[i]])
     86           low[x]=min(low[x],dfn[u[i]]);
     87       }
     88   if(dfn[x]==low[x])
     89     {
     90       sum++;
     91       for(;q[t]!=x;t--)
     92         {
     93           belong[q[t]]=sum;
     94           f[q[t]]=0; 
     95         }
     96       belong[x]=sum;
     97       f[x]=0;
     98       t--;
     99     }
    100 }
    101 int main()
    102 {
    103    n=read();
    104    m=read();
    105    S=read();
    106    T=read();
    107    for(int i=1;i<=m;i++)
    108      {
    109        int a1=read(),a2=read(),a3=read();
    110        jia(a1,a2,a3);
    111        jia(a2,a1,0);
    112      }
    113    for(;bfs();)
    114      dinic(S,0x7fffffff);
    115    for(int i=1;i<=n;i++)
    116      if(!dfn[i])
    117        tarjin(i);
    118    for(int i=2;i<=cnt;i+=2)
    119      if(v[i])
    120        printf("0 0
    ");
    121      else
    122        {
    123          if(belong[fr[i]]==belong[u[i]])
    124            printf("0 ");
    125          else
    126            printf("1 ");
    127          if(belong[fr[i]]==belong[S]&&belong[u[i]]==belong[T])
    128            printf("1
    ");
    129          else
    130            printf("0
    ");
    131        }
    132    return 0;
    133 }
    134 
  • 相关阅读:
    Access导入MSSQL SERVER
    Centos8停用、启用、查看当前启用的端口
    CentOS下使用VI
    CentOS关机与重启命令
    华为云CentOS8安装FTP
    华为云CentOS8安装JDK
    华为云CentOS8安装Nginx
    华为云CentOS8安装Redis
    华为云CentOS8安装MYSQL
    oracle 本地导入imp bat的写法
  • 原文地址:https://www.cnblogs.com/xiw5/p/5658619.html
Copyright © 2011-2022 走看看