[bzoj2229][Zjoi2011]最小割
生活随笔
收集整理的這篇文章主要介紹了
[bzoj2229][Zjoi2011]最小割
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
來自FallDream的博客,未經允許,請勿轉載,謝謝。
?
小白在圖論課上學到了一個新的概念——最小割,下課后小白在筆記本上寫下了如下這段話: “對于一個圖,某個對圖中結點的劃分將圖中所有結點分成兩個部分,如果結點s,t不在同一個部分中,則稱這個劃分是關于s,t的割。 對于帶權圖來說,將所有頂點處在不同部分的邊的權值相加所得到的值定義為這個割的容量,而s,t的最小割指的是在關于s,t的割中容量最小的割” 現給定一張無向圖,小白有若干個形如“圖中有多少對點它們的最小割的容量不超過x呢”的疑問,小藍雖然很想回答這些問題,但小藍最近忙著挖木塊,于是作為仍然是小藍的好友,你又有任務了。
T<=10,n<=150,m<=3000,q<=30
?
最小割樹(分治+最小割)
每次從要分治的部分中選出兩個點求最小割,并且更新與S相連的部分的點和與T相連的部分的點的答案,然后切成兩半分別分治下去即可。
總共分治n次
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #define MN 150 #define INF 2000000000 using namespace std; inline int read() {int x = 0 , f = 1; char ch = getchar();while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar();}while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}return x * f; } vector<int> v[MN*MN+5]; bool in[MN+5]; int n,m,head[MN+5],cnt=1,tot=0,d[MN+5],q[MN+5],top,c[MN+5],Ans[MN+5][MN+5],bel[MN+5],S,T; struct edge{int to,next,w,tot;}e[30005]; inline void ins(int f,int t,int w) {e[++cnt]=(edge){t,head[f],w,w};head[f]=cnt;e[++cnt]=(edge){f,head[t],0,0};head[t]=cnt; }void rebuild(){for(int i=2;i<=cnt;++i)e[i].w=e[i].tot;}void Dfs(int x) {v[bel[x]=tot].push_back(x);for(int i=head[x];i;i=e[i].next)if(!bel[e[i].to]) Dfs(e[i].to); }int dfs(int x,int f) {if(x==T) return f;int used=0;for(int&i=c[x];i;i=e[i].next)if(e[i].w&&d[e[i].to]==d[x]+1){int w=dfs(e[i].to,min(f-used,e[i].w));used+=w;e[i].w-=w;e[i^1].w+=w;if(used==f) return used;}return d[x]=-1,used; }bool bfs() {memset(d,0,sizeof(d));int i,j;for(d[q[top=i=1]=S]=1;i<=top;++i)for(j=c[q[i]]=head[q[i]];j;j=e[j].next)if(e[j].w&&!d[e[j].to]) d[q[++top]=e[j].to]=d[q[i]]+1;return d[T]; }void Get(int x) {in[x]=1;for(int i=head[x];i;i=e[i].next)if(!in[e[i].to]&&e[i].w) Get(e[i].to); }void Solve(int now) {if(v[now].size()<2) {v[now].clear();return;}S=v[now][0],T=v[now][1];rebuild();int ans=0;while(bfs()) ans+=dfs(S,INF);memset(in,0,sizeof(in));Get(S);for(int i=1;i<=n;++i)for(int j=i+1;j<=n;++j)if(in[i]^in[j]) Ans[i][j]=min(Ans[i][j],ans);for(int i=1;i<=n;++i)if(bel[i]==now)bel[i]=(in[i]?tot+1:tot+2),v[bel[i]].push_back(i);int pre=tot;tot+=2;Solve(pre+1);Solve(pre+2);v[now].clear(); }int main() {for(int cas=read();cas;--cas){n=read();m=read();cnt=1;tot=0;memset(head,0,sizeof(head));memset(bel,0,sizeof(bel));memset(Ans,127,sizeof(Ans));for(int i=1;i<=m;++i){int x=read(),y=read(),w=read();ins(x,y,w);ins(y,x,w);}for(int i=1;i<=n;++i)if(!bel[i]) ++tot,Dfs(i),Solve(tot);for(int i=1;i<=n;++i)for(int j=i+1;j<=n;++j)Ans[i][j]>INF?Ans[i][j]=0:0;for(int q=read();q;--q){int num=read(),ans=0;for(int i=1;i<n;++i)for(int j=i+1;j<=n;++j)if(Ans[i][j]<=num) ++ans;printf("%d\n",ans); }puts("");}return 0; }轉載于:https://www.cnblogs.com/FallDream/p/bzoj2229.html
總結
以上是生活随笔為你收集整理的[bzoj2229][Zjoi2011]最小割的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [转]机器学习和深度学习资料汇总【01】
- 下一篇: 人工智能岗位替代----办公文员