最近写的代码都挺长的啊...
下面说一下最小割吧。
以下内容引自:这里
首先介绍一个概念:
点连通度:一个具有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; }