日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JZOJ 5630. 【NOI2018模拟4.4】Connection

發布時間:2025/3/15 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JZOJ 5630. 【NOI2018模拟4.4】Connection 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Description

給定一張N個點M條邊的連通無向圖,問最少需要斷開多少條邊使得這張圖不再連通。

Input

第一行兩個整數N,M含義如題所示。
接下來M行,每行兩個正整數x,y,表示x和y之間有一條無向邊。
輸入數據保證連通性且無自環。

Output

輸出最少需要斷開多少條邊。

Sample Input

5 7
1 2
2 3
3 4
4 5
5 1
2 4
1 3

Sample Output

2

Data Constraint

Solution

  • 直接做 N?1 次最小割?

  • 聽說會超時……

  • 于是我們用一種全新的方法——最小割樹!

  • 一開始所有點都在同一個集合中,隨意取兩點 s,t 為源、匯點做一遍最小割。

  • 之后點就被割成了兩個集合,即 s.t 所在的兩個集合。

  • 再對這兩個集合分治遞歸下去,繼續做最小割。

  • 這樣求出來的 N?1 個最小割中的最小值即為答案。

Code

#include<cstdio> #include<cstring> #include<cctype> using namespace std; const int N=305,M=N*15,inf=1e9; int n,m,tot=1,ans=inf,s,t; int first[N],nex[M],en[M],w[M]; int dis[N],gap[M],cur[N],a[N],b[N]; bool bz[N]; inline int read() {int X=0,w=0; char ch=0;while(!isdigit(ch)) w|=ch=='-',ch=getchar();while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X; } inline int min(int x,int y) {return x<y?x:y; } inline void ins(int x,int y,int z) {nex[++tot]=first[x];first[x]=tot;en[tot]=y;w[tot]=z; } inline void insert(int x,int y) {ins(x,y,1),ins(y,x,1); } int sap(int x,int y) {if(x==t) return y;int use=0;for(int i=cur[x];i;i=nex[i])if(w[i] && dis[x]==dis[en[i]]+1){cur[x]=i;int num=sap(en[i],min(w[i],y-use));w[i]-=num,w[i^1]+=num,use+=num;if(use==y || dis[s]>m) return use;}cur[x]=first[x];if(!--gap[dis[x]]) dis[s]=m+1;gap[++dis[x]]++;return use; } void dfs(int x) {bz[x]=true;for(int i=first[x];i;i=nex[i])if(w[i] && !bz[en[i]]) dfs(en[i]); } void solve(int l,int r) {if(l==r) return;s=a[l],t=a[r];memset(gap,0,sizeof(gap));memset(dis,0,sizeof(dis));for(int i=2;i<=tot;i+=2) w[i]=w[i^1]=w[i]+w[i^1]>>1;gap[0]=m;for(int i=1;i<=n;i++) cur[i]=first[i];int sum=0;while(dis[s]<=m) sum+=sap(s,inf);ans=min(ans,sum);memset(bz,false,sizeof(bz));dfs(s);int ll=l,rr=r;for(int i=l;i<=r;i++)if(bz[a[i]]) b[ll++]=a[i]; else b[rr--]=a[i];for(int i=l;i<=r;i++) a[i]=b[i];solve(l,ll-1);solve(ll,r); } int main() {n=read(),m=read();if(m==n-1) return 0&puts("1");for(int i=1;i<=m;i++) insert(read(),read());for(int i=1;i<=n;i++) a[i]=i;solve(1,n);printf("%d",ans);return 0; }

總結

以上是生活随笔為你收集整理的JZOJ 5630. 【NOI2018模拟4.4】Connection的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。