標籤:style blog http color io os ar for strong
題意:求點聯通度
首先看了別人的題解還是不曉得只枚舉匯點的原因覺得行不通
關於求點聯通度的建圖方法 轉自http://hi.baidu.com/lerroy312/item/5a5f36f2f5bba61bcf9f322e
點連通度的定義:一個具有N個點的圖G中,在去掉任意k-1個頂點後(1<=k<=N),所得的子圖仍然連通,去掉K個頂點後不連通,則稱G是K連通圖,K稱作圖G的連通度,記作K(G)。
獨立軌:A,B是圖G(有向無向均可)的兩個頂點,我們稱為從A到B的兩兩無公用內頂的軌為獨立軌,其最大的條數記作p(A,B)。
在中有一個具有7個定點的連通圖,從頂點1到頂點3有3條獨立軌,即p(1,3)=3;
1—2—3 , 1—7—3 , 1—6—5—4—3
如果分別從這3條獨立軌中,每條軌抽出一個內點,在G圖中刪掉,則圖不連通。若連通圖G的兩兩不相鄰頂點間的最大獨立軌數最小的P(A,B)值即為K(G)。若G為完全圖(兩兩點可達),則
K(G)=n-1,即完全把某個點的所有邊刪掉後才不連通。既然獨立軌是只能經過一次的邊,那麼可以構造網路流模型,其中每條邊的容量為1,就可以限制只經過一次。
構建網路流模型:
若G為無向圖:
(1)原G圖中的每個頂點V變成N網中的兩個頂點V`和V``,頂點V`至V``有一條弧容量為1;
(2)原圖G中的每條邊e=UV,在N網中有兩條弧e`=U``V`,e``=V``U`與之對應,e`與e``容量均為無窮;
(3)以A``為源點,B`為匯點,求最大流。
若G為有向圖
(1)原G圖中的每個頂點V變成N網中的兩個頂點V`和V``,頂點V`至V``有一條容量為1的弧;
(2)原G圖中的每條弧e=UV變成一條有向軌U`U``V`V``,其中軌上的弧U``V`的容量為無窮;
(3)以A``為源點,B`為匯點求最大流。
上面的模型只是求出了以A為源點B為匯點的最大流max_flow,等價於在G中只要去掉max_flow個點就會使得A與B不連通。而圖的連通度是要求去掉最少的點使得整個圖不連通,做法是固定一個點為源點,枚舉與源點不相鄰的點為匯點,求最大流。在所有的枚舉結果中最小的max_flow值就是要求的K(G).注意如果某次枚舉的匯點求出 的最大流為無窮則說明此此枚舉的源點與匯點是強連通的。如果所有的枚舉結果都為無窮,則說明整個圖G是強連通的,需要去掉n-1個點才能破壞其連通性。
所有具有流量為1的弧(V`,V``)對應的V頂點組成一個割頂集
通過求連通度可以得到一個結論:G是K的連通圖,k>=2,則任意K個頂點共圈。
求邊連通度總結:
同樣引入獨立軌的概念,只是在這裡叫弱獨立軌,同樣在每條弱獨立軌中只有去掉某一條邊就可以使起點到終點不連通,現在整個圖G的邊連通度就是要找出任意兩點的弱獨立軌的最小值。如果圖G為完全圖,則K`(G)為n-1。
構建一個網路N
若G為無向圖:
1. 原G圖中的每條邊e=UV變成兩條邊e`=UV,e``=VU,容量都為1;
2. 固定一個點為源點,枚舉與源點不相鄰的為匯點,求最大流max_flow,保留最小的max_flow即為圖的邊連通度。
若G為有向圖:
1. 原G圖中每條有向邊容量為1;
2. 此步驟與無向圖的步驟2相同。
求出的殘餘網路中,流量為1的弧e`=(u,v),則e`就是橋。
從圖的邊連通度中可以得到以下結論:
1. A是有向圖G的一個頂點,如果A與G的其他所有點V間的最小值為K,則G中存在以A為根的K棵無公用邊的產生樹;
2. 設G是有向圖,0<k<=K`(G),L是0至k之間任意一個整數,對於圖G的任意一對頂點(u,v)來說,存在U到V的L條弱獨立有向軌,同時存在從V到U的L-k條弱獨立有向軌。
#include <map>#include <set>#include <list>#include <cmath>#include <ctime>#include <deque>#include <stack>#include <queue>#include <cctype>#include <cstdio>#include <string>#include <vector>#include <climits>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#define LL long long#define PI 3.1415926535897932626using namespace std;int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}#define MAXN 110const int INF = 0x3f3f3f3f;int p[MAXN];int cap[MAXN][MAXN],flow[MAXN][MAXN];int a[MAXN];int N,M;int Edmonds_karp(int s, int t){ memset(flow,0,sizeof(flow)); queue<int>q; int F = 0; while (true) { memset(a,0,sizeof(a)); a[s] = INF; q.push(s); while (!q.empty()) { int u = q.front(); q.pop(); for (int i = 1; i <= 2 * N; i++) if (!a[i] && cap[u][i] > flow[u][i]) { a[i] = min(a[u],cap[u][i] - flow[u][i]); p[i] = u; q.push(i); } } if (a[t] == 0) break; for (int u = t; u != s; u = p[u]) { flow[p[u]][u] += a[t]; flow[u][p[u]] -= a[t]; } F += a[t]; } return F;}int main(){ //freopen("sample.txt","r",stdin); while (scanf("%d%d",&N,&M) != EOF) { memset(cap,0,sizeof(cap)); for (int i = 1; i <= N; i++) cap[i][i + N] = 1; while (M--) { int u,v; scanf(" (%d,%d)",&u,&v); v++;u++; cap[u + N][v] = INF; cap[v + N][u] = INF; } int ans = INF; for (int i = 1; i <= N; i++) for (int j = 1; j <= N; j++) { if (i == j) continue; ans = min(ans,Edmonds_karp(i + N ,j)); } if (ans == INF) ans = N; printf("%d\n",ans); } return 0;}
UVALIVE 3031 Cable TV Network