標籤:namespace eve 等等 return 重複 str string out cto
【Luogu1345】奶牛的電信(網路流)題面題目描述
農夫約翰的奶牛們喜歡通過電郵保持聯絡,於是她們建立了一個奶牛電腦網路,以便互相交流。這些機器用如下的方式發送電郵:如果存在一個由c台電腦組成的序列a1,a2,...,a(c),且a1與a2相連,a2與a3相連,等等,那麼電腦a1和a(c)就可以互發電郵。
很不幸,有時候奶牛會不小心踩到電腦上,農夫約翰的車也可能碾過電腦,這台倒黴的電腦就會壞掉。這意味著這台電腦不能再發送電郵了,於是與這台電腦相關的串連也就不可用了。
有兩頭奶牛就想:如果我們兩個不能互發電郵,至少需要壞掉多少台電腦呢?請編寫一個程式為她們計算這個最小值。
以如下網路為例:
1*
/ 3 - 2*
這張圖畫的是有2條串連的3台電腦。我們想要在電腦1和2之間傳送資訊。電腦1與3、2與3直接連通。如果電腦3壞了,電腦1與2便不能互發資訊了。
輸入輸出格式
輸入格式:
第一行 四個由空格分隔的整數:N,M,c1,c2.N是電腦總數(1<=N<=100),電腦由1到N編號。M是電腦之間串連的總數(1<=M<=600)。最後的兩個整數c1和c2是上述兩頭奶牛使用的電腦編號。串連沒有重複且均為雙向的(即如果c1與c2相連,那麼c2與c1也相連)。兩台電腦之間至多有一條串連。電腦c1和c2不會直接相連。
第2到M+1行 接下來的M行中,每行包含兩台直接相連的電腦的編號。
輸出格式:
一個整數表示使電腦c1和c2不能互相通訊需要壞掉的電腦數目的最小值。
題解
網路流的建邊永遠都是套路
而網路流的套路永遠都是建邊
把建邊一些,\(S、T\)賦個值
輕輕鬆鬆搞定。。。
這道題目很顯然,要求的是最小割。。。。
但是是點的最小割。。。
這就懵逼了。。。
怎麼辦呢?
當然是類似LCT的加一個點出來呀
然後把所有連出去的邊都連在這個點上面,
然後再從當前點連向這個點,
如果這個點要被割掉,那麼,這條邊就不走了。
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<algorithm>#include<set>#include<map>#include<queue>#include<vector>using namespace std;#define MAXL 50000#define MAX 200#define INF 1e8inline int read(){ int x=0,t=1;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=-1,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return x*t;}struct Line{ int v,next,w;}e[MAXL];int h[MAX],cnt;int n,m,S,T;inline void Add(int u,int v,int w){ e[cnt]=(Line){v,h[u],w}; h[u]=cnt++;}int level[MAX];int cur[MAX];bool BFS(){ memset(level,0,sizeof(level)); level[S]=1; queue<int> Q; Q.push(S); while(!Q.empty()) { int u=Q.front();Q.pop(); for(int i=h[u];i!=-1;i=e[i].next) { int v=e[i].v; if(e[i].w&&!level[v]) level[v]=level[u]+1,Q.push(v); } } return level[T];}int DFS(int u,int flow){ if(flow==0||u==T)return flow; int ret=0; for(int &i=cur[u];i!=-1;i=e[i].next) { int v=e[i].v; if(e[i].w&&level[v]==level[u]+1) { int dd=DFS(v,min(flow,e[i].w)); flow-=dd;ret+=dd; e[i].w-=dd;e[i^1].w+=dd; } } return ret;}int Dinic(){ int ret=0; while(BFS()) { for(int i=1;i<=n+n;++i)cur[i]=h[i]; ret+=DFS(S,INF); } return ret;}int main(){ memset(h,-1,sizeof(h)); n=read();m=read();S=read()+n;T=read(); for(int i=1;i<=m;++i) { int u=read(),v=read(); Add(u+n,v,INF);Add(v,u+n,0); Add(v+n,u,INF);Add(u,v+n,0); } for(int i=1;i<=n;++i) Add(i,i+n,1),Add(i+n,i,0); cout<<Dinic()<<endl; return 0;}
【Luogu1345】奶牛的電信(網路流)