Luogu P1345 [usaco 5.4] Telecowmunication,
Description
Farmer John's cows liked to keep in touch via e-mails, so they established a dairy computer network to communicate with each other. These machines send emails in the following way: if there is a sequence of a1, a2,..., consisting of c computers ,..., a (c), a1 is connected to a2, a2 is connected to a3, etc. Then a1 and a (c) can send emails to each other.
Unfortunately, sometimes the cows accidentally step on the computer, and John's car may run over the computer, and this bad computer will break down. This means that the computer can no longer send emails, so the connection to the computer will become unavailable.
Two cows think: if the two of us cannot send emails to each other, how many computers need to be damaged? Compile a program to calculate the minimum value for them.
Take the following network as an example:
1 */3-2 *
This picture shows three computers with two connections. We want to transfer information between computer 1 and computer 2. Computers 1 and 3, 2 and 3 are directly connected. If the computer 3 breaks down, the computer 1 and 2 cannot send messages to each other.
Input/Output Format
Input Format:
The four integers separated by spaces in the first line: N, M, c1, and c2.N are the total number of computers (1 <=n <= 100. M is the total number of connections between computers (1 <= M <= 600 ). The last two integers c1 and c2 are the computer numbers used by the above two cows. The connection is not repeated and is bidirectional (that is, if c1 is connected to c2, c2 and c1 are also connected ). There is at most one connection between the two computers. The computer c1 and c2 are not directly connected.
The numbers of two computers that are directly connected to each other are listed in the following MB lines from 2nd to M + 1.
Output Format:
An integer indicates the minimum number of computers that need to be damaged so that the computer c1 and c2 cannot communicate with each other.
Input and Output sample input sample #1: Copy
3 2 1 21 32 3
Output example #1: Copy
1
It can be seen at a glance that it is a minimal cut ..
After the split, run the Dinic on one side.
Edge with the link weight of 1 before the split point
The edge of the connection INF given in the question
The key is how to write the code. QWQ
I thought about it for a long time,
After reading this, I found a clever method.
Note the S and T options,
#include<cstdio>#include<cstring>#include<queue>using namespace std;const int MAXN=801,INF=5*1e8+10;inline char nc(){ static char buf[MAXN],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;}inline int read(){ char c=nc();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=nc();} return x*f;}int S=0,T=3001;struct node{ int u,v,flow,nxt;}edge[MAXN*20];int head[MAXN],cur[MAXN],num=0;inline void add_edge(int x,int y,int z){ edge[num].u=x; edge[num].v=y; edge[num].flow=z; edge[num].nxt=head[x]; head[x]=num++;}inline void AddEdge(int x,int y,int z) { add_edge(x,y,z); add_edge(y,x,0);}int deep[MAXN];inline bool BFS(){ memset(deep,0,sizeof(deep)); deep[S]=1; queue<int>q; q.push(S); while(q.size()!=0) { int p=q.front(); q.pop(); for(int i=head[p];i!=-1;i=edge[i].nxt) if(!deep[edge[i].v]&&edge[i].flow) { deep[edge[i].v]=deep[p]+1;q.push(edge[i].v); if(edge[i].v==T) return 1; } } return deep[T];}int DFS(int now,int nowflow){ if(now==T||nowflow<=0) return nowflow; int totflow=0; for(int &i=cur[now];i!=-1;i=edge[i].nxt) { if(deep[edge[i].v]==deep[now]+1&&edge[i].flow) { int canflow=DFS(edge[i].v,min(nowflow,edge[i].flow)); edge[i].flow-=canflow;edge[i^1].flow+=canflow; totflow+=canflow; nowflow-=canflow; if(nowflow<=0) break; } } return totflow;}int Dinic(){ int ans=0; while(BFS()) { memcpy(cur,head,sizeof(head)); ans+=DFS(S,INF); } return ans;}int main(){ #ifdef WIN32 freopen("a.in","r",stdin); #else #endif memset(head,-1,sizeof(head)); int N=read(),M=read(),A=read(),B=read(); for(int i=1;i<=N;i++) AddEdge(i+N,i,1); for(int i=1;i<=M;i++) { int x=read(),y=read(); AddEdge(x,y+N,INF); AddEdge(y,x+N,INF); } S=A;T=B+N; printf("%d",Dinic()); return 0;}