最近寫的代碼都挺長的啊...
下面說一下最小割吧。
以下內容引自:這裡
首先介紹一個概念:
點連通度:一個具有N個頂點的圖G,去除K個頂點後,圖成為非連通圖,去除任意K-1個頂點後,圖仍為連通圖。責成圖G為K連通圖。
獨立軌:A,B是圖G中兩個頂點,從A至B的無公用內頂點的路徑叫做獨立軌,其最大條數記為p(A,B);
如中,將A=1,B=5;那麼該圖的最大獨立軌數量為3
1-2-3-5,1-4-5,1-7-6-5;三條。
在這三條獨立軌中,每條切除一個內點,該圖的成為非連通圖。如果p(G)=N-1,則該圖為強連通圖。
可見p(A,B)=K(G)。也就是圖G獨立軌的最大條數為圖G的連通度。
由於每個內點只能用一次,可以套最大流模型...
將頂點v分割為v,v',e=(v,v')容量為1;做一次最大流就可以得出源點到匯點的最小割。
G無向圖:
(1)頂點v分割為v,v'。e(v,v')容量為1;
(2)圖中的無向邊設為2條有向邊,e(u,v)-->e(u',v)=INF,e(v',u)=INF;
(3)枚舉源點u'和匯點v做最大流。
G有向圖類似。
若結果流出的值為INF,則該圖為強連通,去除N個頂點才能破壞連通性。
所有具有流量為1的弧(V,V')對應的V頂點組成一個割頂集
通過求連通度可以得到一個結論:G是K的連通圖,k>=2,則任意K個頂點共圈。
邊連通度:
解法類似,不過邊連通,點可以走很多次,邊只能走一次。
(1)對於無向邊e(u,v) 在(u,v),(v,u)之間添加容量為1的流邊。
(2)枚舉源點匯點,求最大流,即為邊連通度。
求出的殘餘網路中,流量為1的弧e`=(u,v),則e`就是割邊。
#include<iostream>#include<string>#include<cstdio>#include<cstdlib>#include<algorithm>#define MN 111#define INF 0x3FFFFFFF#define CC(a) memset( a,0,sizeof(a) )#define FF(i,N) for( int i=0;i<N;i++ )template<class T>void inline checkmin( T &a,T b ){ if( a>b||a==-1 ) a=b; }template<class T>void inline checkmax( T &a,T b ){ if( a<b ) a=b; }using namespace std;int maze[MN][MN],map[MN][MN],dis[MN],cur[MN],gap[MN],pre[MN];int N,M,s,t;void setG(){ CC(map); FF( i,N ) map[i][i+N]=1; int u,v; FF( i,M ){ scanf( " (%d,%d)",&u,&v ); map[u+N][v]=map[v+N][u]=INF; }}void initG(){ FF(i,N<<1)FF(j,N<<1) maze[i][j]=map[i][j];}int sap( int s,int t ){ CC(cur),CC(gap),CC(dis); int u=pre[s]=s,maxflow=0,aug=-1; gap[0]=2*N; while( dis[s]<2*N ){loop: for( int v=cur[u];v<2*N;v++ ) if( maze[u][v]&&dis[u]==dis[v]+1 ) { pre[v]=u; cur[u]=v; checkmin( aug,maze[u][v] ); u=v; if( v==t ) { maxflow+=aug; for( u=pre[u];v!=s;v=u,u=pre[u] ) maze[u][v]-=aug,maze[v][u]+=aug; aug=-1; } goto loop; } int mind=2*N; for( int v=0;v<2*N;v++ ) if( maze[u][v]&&mind>dis[v] ) { mind=dis[v]; cur[u]=v; } if( --gap[dis[u]]==0 ) break; gap[dis[u]=mind+1]++; u=pre[u]; } return maxflow;}int main(){ while( scanf("%d%d",&N,&M)!=EOF ) { int ans=INF; setG(); for( int i=0;i<N;i++ ) for( int j=i+1;j<N;j++ ) { initG(); checkmin( ans,sap(i+N,j) ); //printf( "ans:%d\n",ans ); } if( ans==INF ) printf( "%d\n",N ); else printf( "%d\n",ans ); } return 0;}