首页 > 代码库 > 【BZOJ2229】【ZJOI2011】最小割
【BZOJ2229】【ZJOI2011】最小割
冷门知识点……
原题:
小白在图论课上学到了一个新的概念——最小割,下课后小白在笔记本上写下了如下这段话: “对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点s,t不在同一个部分中,则称这个划分是关于s,t的割。 对于带权图来说,将所有顶点处在不同部分的边的权值相加所得到的值定义为这个割的容量,而s,t的最小割指的是在关于s,t的割中容量最小的割” 现给定一张无向图,小白有若干个形如“图中有多少对点它们的最小割的容量不超过x呢”的疑问,小蓝虽然很想回答这些问题,但小蓝最近忙着挖木块,于是作为仍然是小蓝的好友,你又有任务了。
1<=u,v<=n,0<=c<=106
分治最小割:O(跑得过)时间处理n个点两两之间的最小割
每次在当前集合中随意找两个点,最小割成两个集合,递归处理这两个集合,开O(n^2)数组记录答案
注意初始化
没了
(注意"两组测试数据之间用空行隔开",否则PE)
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 const int oo=168430090; 8 int rd(){int z=0,mk=1; char ch=getchar(); 9 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)mk=-1; ch=getchar();} 10 while(ch>=‘0‘&&ch<=‘9‘){z=(z<<3)+(z<<1)+ch-‘0‘; ch=getchar();} 11 return z*mk; 12 } 13 struct ddd{int nxt,y,v,rvs;}e[6100]; int lk[210],ltp=0; 14 inline void ist(int x,int y,int z){ 15 e[++ltp].nxt=lk[x],lk[x]=ltp,e[ltp].y=y,e[ltp].v=z,e[ltp].rvs=ltp+1; 16 e[++ltp].nxt=lk[y],lk[y]=ltp,e[ltp].y=x,e[ltp].v=z,e[ltp].rvs=ltp-1; 17 } 18 int n,m,qst; int s,t; 19 int lvl[210]; 20 int q[210],hd=0; 21 bool st[210]; 22 int quq[210],tmp[210]; 23 int mnct[210][210]; 24 bool gtlvl(){ 25 memset(lvl,0,sizeof(lvl)); 26 q[hd=1]=s,lvl[s]=1; 27 for(int k=1;k<=hd;++k) 28 for(int i=lk[q[k]];i;i=e[i].nxt)if(e[i].v && !lvl[e[i].y]) 29 lvl[e[i].y]=lvl[q[k]]+1,q[++hd]=e[i].y; 30 return lvl[t]; 31 } 32 int mxflw(int x,int y){ 33 if(x==t) return y; 34 int bwl=0,flw=0; 35 for(int i=lk[x];i && bwl<y;i=e[i].nxt)if(e[i].v && lvl[e[i].y]==lvl[x]+1) 36 if((flw=mxflw(e[i].y,min(y-bwl,e[i].v)))){ 37 bwl+=flw; 38 e[i].v-=flw,e[e[i].rvs].v+=flw; 39 } 40 if(!bwl) lvl[x]=0; 41 return bwl; 42 } 43 void gtst(){ 44 q[hd=1]=s,st[s]=true; 45 for(int k=1;k<=hd;++k)for(int i=lk[q[k]];i;i=e[i].nxt) 46 if(e[i].v && !st[e[i].y]) st[e[i].y]=true,q[++hd]=e[i].y; 47 } 48 int dnc(){ 49 int bwl=0,flw=0; 50 while(gtlvl())while((flw=mxflw(s,oo))) bwl+=flw; 51 memset(st,0,sizeof(st)); 52 gtst(); 53 return bwl; 54 } 55 void sprt(int l,int r){ 56 if(l>=r) return ; 57 for(int i=1;i<=ltp;++i) e[i].v=e[e[i].rvs].v=(e[i].v+e[e[i].rvs].v)>>1; 58 s=quq[l],t=quq[r]; 59 int mxflw=dnc(); 60 for(int i=1;i<=n;++i)if(st[i])for(int j=1;j<=n;++j)if(!st[j]) 61 mnct[j][i]=mnct[i][j]=min(mnct[i][j],mxflw); 62 int hd1=l,hd2=r; 63 for(int i=l;i<=r;++i) tmp[(st[quq[i]] ? hd2-- : hd1++)]=quq[i]; 64 for(int i=l;i<=r;++i) quq[i]=tmp[i]; 65 sprt(l,hd1-1),sprt(hd2+1,r); 66 } 67 void clr(){ memset(lk,0,sizeof(lk)),ltp=0; memset(mnct,10,sizeof(mnct));} 68 int main(){//freopen("ddd.in","r",stdin); 69 int T; cin>>T; while(T--){ clr(); 70 cin>>n>>m; 71 for(int i=1;i<=n;++i) quq[i]=i; 72 int l,r,v,cnt=0; 73 while(m--) l=rd(),r=rd(),v=rd(),ist(l,r,v); 74 sprt(1,n); 75 cin>>qst; 76 while(qst--){ 77 v=rd(),cnt=0; 78 for(int i=1;i<=n;++i)for(int j=i+1;j<=n;++j)if(mnct[i][j]<=v) ++cnt; 79 printf("%d\n",cnt); 80 } 81 cout<<endl; 82 continue; 83 } 84 return 0; 85 }
【BZOJ2229】【ZJOI2011】最小割
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。