zoukankan      html  css  js  c++  java
  • bzoj2229: [Zjoi2011]最小割(分治最小割+最小割树思想)

    2229: [Zjoi2011]最小割

    题目:传送门 

    题解:

       一道非常好的题目啊!!!

       蒟蒻的想法:暴力枚举点对跑最小割记录...绝对爆炸啊....

       开始怀疑是不是题目骗人...难道根本不用网络流???一看路牌....分治最小割?最小割树?

       然后开始各种%论文...

       简单来说吧,根据各种本蒟蒻不会证明的理论,那么:所有最小割都不是完全独立的,总共有n-1种(也就是树上的n-1条边)最小割 恰好和树的定义一样啊!

       那么用一个solve递归函数来解决,一开始任意找两个点作为st和ed来最小割,然后分治,在分开的两个集合中继续递归,用数组记录答案

       以上都是根据边所进行的离线操作,然后输入Q个询问,直接在线输出答案就ok

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cmath>
      5 #include<algorithm>
      6 using namespace std;
      7 const int inf=999999999;
      8 struct node
      9 {
     10     int x,y,c,next,other;
     11 }a[210000];int len,last[110000];
     12 int st,ed,n,m,T,ans;
     13 void ins(int x,int y,int 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=c;
     22     a[len].next=last[y];last[y]=len;
     23     
     24     a[k1].other=k2;
     25     a[k2].other=k1;
     26 }
     27 int list[110000],h[110000],head,tail;
     28 bool bt_h()
     29 {
     30     memset(h,0,sizeof(h));h[st]=1;
     31     list[1]=st;head=1;tail=2;
     32     while(head!=tail)
     33     {
     34         int x=list[head];
     35         for(int k=last[x];k;k=a[k].next)
     36         {
     37             int y=a[k].y;
     38             if(h[y]==0 && a[k].c)
     39             {
     40                 h[y]=h[x]+1;
     41                 list[tail++]=y;
     42             }
     43         }
     44         head++;
     45     }
     46     if(h[ed])return true;
     47     return false;
     48 }
     49 int find_flow(int x,int flow)
     50 {
     51     if(x==ed)return flow;
     52     int s=0,t;
     53     for(int k=last[x];k;k=a[k].next)
     54     {
     55         int y=a[k].y;
     56         if(h[y]==h[x]+1 && a[k].c && s<flow)
     57         {
     58             s+=t=find_flow(y,min(a[k].c,flow-s));
     59             a[k].c-=t;a[a[k].other].c+=t;
     60         }
     61     }
     62     if(s==0)h[x]=0;
     63     return s;
     64 }
     65 int d[110000],num[110000],sta[110000],anss[1100][1100];
     66 void re_num(int x)
     67 {
     68     num[x]=1;
     69     for(int k=last[x];k;k=a[k].next)
     70     {
     71         int y=a[k].y;
     72         if(a[k].c && !num[y])
     73             re_num(y);
     74     }
     75 }
     76 void solve(int l,int r)
     77 {
     78     if(l==r)return ;
     79     for(int i=1;i<=len;i+=2)a[i].c=a[i+1].c=(a[i].c+a[i+1].c)>>1;//将边权重置 
     80     st=d[l];ed=d[r];ans=0;
     81     while(bt_h())ans+=find_flow(st,inf);
     82     memset(num,0,sizeof(num));
     83     re_num(st);
     84     for(int i=1;i<=n;i++)
     85         if(num[i])
     86             for(int j=1;j<=n;j++)
     87                 if(!num[j])
     88                     anss[i][j]=anss[j][i]=min(anss[i][j],ans);
     89     int L=l,R=r;
     90     for(int i=l;i<=r;i++)
     91     {
     92         if(num[d[i]])sta[L++]=d[i];
     93         else      sta[R--]=d[i];
     94     }
     95     for(int i=l;i<=r;i++)d[i]=sta[i];
     96     solve(l,L-1);solve(R+1,r);//分治,递归 
     97 }
     98 int main()
     99 {
    100     scanf("%d",&T);
    101     while(T--)
    102     {
    103         scanf("%d%d",&n,&m);
    104         len=0;memset(last,0,sizeof(last));int x,y,c;
    105         for(int i=1;i<=m;i++)scanf("%d%d%d",&x,&y,&c),ins(x,y,c);
    106         for(int i=1;i<=n;i++)d[i]=i;memset(anss,63,sizeof(anss));
    107         solve(1,n);
    108         int Q;scanf("%d",&Q);
    109         while(Q--)
    110         {
    111             scanf("%d",&x);int cnt=0;
    112             for(int i=1;i<=n;i++)
    113                 for(int j=i+1;j<=n;j++)
    114                     if(anss[i][j]<=x)
    115                         cnt++;
    116             printf("%d
    ",cnt);
    117         }
    118         printf("
    ");
    119     }
    120     return 0;
    121 }
  • 相关阅读:
    接口的显式实现和隐式实现
    MVC
    委托
    测试用例(TestCase)
    The remote server returned an error: NotFound.
    事件
    WCF大数据量传输配置
    多态随笔
    领域模型(domain model)
    IQueryable接口和IEnumberable接口
  • 原文地址:https://www.cnblogs.com/CHerish_OI/p/8521791.html
Copyright © 2011-2022 走看看