POJ 1966 最大流最小割…

來源:互聯網
上載者:User

最近寫的代碼都挺長的啊...

下面說一下最小割吧。

以下內容引自:這裡

首先介紹一個概念:

點連通度:一個具有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;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.