最小點割集求解方法:
1.有向圖:把乙個點拆成(i, i+n)2個點,之間容量為1。如果i, j 2個點在原圖中聯通,則將i+n,j相連,容量為無窮大。然後求最小割,可見被最小割割到的都是容量是1的邊,(如果割到一條inf,說明沒有最小點割集。)而且那些邊必將連著i,i+n,於是i就是被割的點。
2.無向圖:把乙個點拆成(i, i+n)2個點,之間容量為1。如果i, j 2個點在原圖中聯通,則將i+n,j相連,容量為無窮大。則將j, i+n相連,容量為無窮大。以下如上。
最小點權割集求解方法:把乙個點拆成(i, i+n)2個點,之間容量為點的權值 其餘同上。
本題思路:列舉每乙個頂點,除了s和t之外,然後求最大流,看看去掉這個頂點和沒去掉有沒有影響。(最大流變小),要從小到大列舉。
這道題因為不能割源點或者匯點 所以在拆源點和匯點的時候 將邊的權值設定為inf 這樣就能保證不會割到源點和匯點了。
還有就是沒有答案的時候的特判 如果源點和匯點直接相連 那麼無論如何都能從源點到達匯點
#include#include#include#include#include#include#include#include#include#include#include#include#includetypedef long long ll;
using namespace std;
const int maxn=405;//jiedian de zui da zhi
const int maxm=800000;//bian de zui da zhi
const int inf=0x3f3f3f3f;
struct node
edge[maxm];
int tol;
int head[maxn];
int dep[maxn];
int gap[maxn];
void init() //remember write it in main function
void addedge(int u,int v,int w)
void bfs(int start,int end)
}}int sap(int start,int end,int n) //n shi jiedian de zui da ge shu ,including source and sink
for(i=0;idep[edge[i].to])
}--gap[dep[u]];
dep[u]=min+1;
++gap[dep[u]];
if(u!=start)u=edge[s[--top]].from;}}
return res;
}int res[maxn];
//雙向圖
int source,sink;
int a[maxn][maxn];
int getmap(int n)}}
}int tt=sap(source, sink+n, 2*n);
return tt;
}int mapx[maxn];
int mapy[maxn];
int main()}}
}if(a[source][sink]==1)//特判
int tt=sap(source, sink+n, 2*n);
printf("%d\n",tt);
int cnt=0;
for(i=1;i<=n;i++)//delete i
int ss=getmap(n);
if(ss如果流沒有改變 說明此點不是割點 恢復
}if(tt==0)break;
}for(i=0;i
最小點割集 poj 1815 貪心列舉
最小點割集 poj 1815 無向圖中至少刪掉多少點使得s,t不連通。最小點聯通度問題,最小點割集 將s看成源點,t看成匯點,將每個點拆成兩個點u和u 之間連容量為1的邊,原來從u到v的邊,變成從u 到v的邊,邊容量都是無窮大,新源點為s 新彙點還是t。題目需要輸出分數最小的點割集,即按字典序排序最...
poj 1815(最小割 割集)
思路 題目要求是剔除多少個點,可以將其轉化為剔除多少條邊,因此需要拆點,將點i拆成i,i n,便容量為1,表示每個人起的傳遞作用只能是一次。然後就是列舉了,刪除某條邊,如果求出的最小割比原來的要小,說明減少的是割邊集。1 include2 include3 include4 include5 inc...
poj1815 最小割點集
題目大意 現代社會人們都靠 通訊。a 與 b 能通訊當且僅當 a 知道 b 的 號或者 a 知道 c 的 號且 c 與 b 能通訊。若 a 知道 b 的 號,那麼 b 也知道 a 的電 話號。然而不好的事情總是會發生在某些人身上,比如他的 本丟了,同時他 又換了 號,導致他跟所有人失去了聯絡。現在給...