• bzoj1797: [Ahoi2009]Mincut 最小割(最小割+强联通tarjan)


    1797: [Ahoi2009]Mincut 最小割

    题目:传送门 


    题解:

       感觉是一道肥肠好的题目。

       第二问其实比第一问简单?

       用残余网络跑强联通,流量大于0才访问。

       那么如果两个点所属的联通分量分别处于st和ed,那一定会被割掉,那么第一问就也会是1

       但是第一问单独处理,就有点GG

       膜了一发题解,发现贼尼玛niu bi:

       还是利用联通分量,如果这条边满流,且连接的两个点所处的联通分量不同,就ok

       太菜了不会证明...大佬hzwer

        


    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cmath>
      5 #include<algorithm>
      6 #define inf 999999999
      7 using namespace std;
      8 typedef long long LL;
      9 struct node
     10 {
     11     int x,y,next,other;LL c;
     12 }a[2110000];int len,last[1110000];
     13 void ins(int x,int y,LL c)
     14 {
     15     int k1,k2;
     16     k1=++len;
     17     a[len].x=x;a[len].y=y;a[len].c=c;
     18     a[len].next=last[x];last[x]=len;
     19     
     20     k2=++len;
     21     a[len].x=y;a[len].y=x;a[len].c=0;
     22     a[len].next=last[y];last[y]=len;
     23     
     24     a[k1].other=k2;
     25     a[k2].other=k1;
     26 }
     27 int n,m,st,ed,head,tail;
     28 int list[1110000],h[1110000];
     29 bool bt_h()
     30 {
     31     memset(h,0,sizeof(h));h[st]=1;
     32     list[1]=st;head=1;tail=2;
     33     while(head!=tail)
     34     {
     35         int x=list[head];
     36         for(int k=last[x];k;k=a[k].next)
     37         {
     38             int y=a[k].y;
     39             if(h[y]==0 && a[k].c>0)
     40             {
     41                 h[y]=h[x]+1;
     42                 list[tail++]=y;
     43             }
     44         }
     45         head++;
     46     }
     47     if(h[ed]>0)return true;
     48     return false;
     49 }
     50 LL find_flow(int x,LL flow)
     51 {
     52     if(x==ed)return flow;
     53     LL s=0,t;
     54     for(int k=last[x];k;k=a[k].next)
     55     {
     56         int y=a[k].y;
     57         if(h[y]==h[x]+1 && a[k].c>0 && s<flow)
     58         {
     59             s+=t=find_flow(y,min(a[k].c,flow-s));
     60             a[k].c-=t;a[a[k].other].c+=t;
     61         }
     62     }
     63     if(s==0)h[x]=0;
     64     return s;
     65 }
     66 int low[1110000],dfn[1110000],belong[1110000],sta[1110000];
     67 int tp,id,cnt;
     68 bool v[1110000];
     69 void dfs(int x)
     70 {
     71     low[x]=dfn[x]=++id;
     72     sta[++tp]=x;v[x]=true;
     73     for(int k=last[x];k;k=a[k].next)
     74     {
     75         int y=a[k].y;
     76         if(a[k].c!=0)
     77         {
     78             if(dfn[y]==-1)
     79             {
     80                 dfs(y);
     81                 low[x]=min(low[x],low[y]);
     82             }
     83             else
     84                 if(v[y]==true)
     85                     low[x]=min(low[x],dfn[y]);
     86         }
     87     }
     88     if(low[x]==dfn[x])
     89     {
     90         int i;cnt++;
     91         do{
     92             i=sta[tp--];
     93             v[i]=false;
     94             belong[i]=cnt;
     95         }while(i!=x);
     96     }
     97 }
     98 int main()
     99 {
    100     scanf("%d%d%d%d",&n,&m,&st,&ed);
    101     len=0;memset(last,0,sizeof(last));
    102     for(int i=1;i<=m;i++)
    103     {
    104         int x,y;LL c;
    105         scanf("%d%d%lld",&x,&y,&c);
    106         ins(x,y,c);
    107     }
    108     LL ans=0;
    109     while(bt_h())ans+=find_flow(st,inf);
    110     memset(sta,0,sizeof(sta));
    111     memset(dfn,-1,sizeof(dfn));
    112     memset(low,0,sizeof(low));
    113     memset(v,false,sizeof(v));
    114     id=tp=cnt=0;
    115     for(int i=1;i<=n;i++)
    116         if(dfn[i]==-1)
    117             dfs(i);
    118     for(int i=1;i<len;i+=2)
    119     {
    120         int x=a[i].x,y=a[i].y;
    121         if(a[i].c!=0){printf("0 0
    ");continue;}
    122         if(belong[x]!=belong[y])printf("1 ");
    123         else printf("0 ");
    124         if((belong[x]==belong[st] && belong[y]==belong[ed]))
    125         printf("1
    ");
    126         else printf("0
    ");
    127     }
    128     return 0;
    129 }
  • 相关阅读:
    6-2 铁轨 uva 514
    并查集基础
    周练7
    周练5
    周练4
    二分查找
    周练3
    2-7 使用不同方式进行定位.py
    2-6 使用title_contains检查页面是否正确
    启用不同浏览器.py
  • 原文地址:https://www.cnblogs.com/CHerish_OI/p/8647110.html
Copyright © 2020-2023  润新知