Pleasant sheep and Big big wolfTime
limit:2000/1000 MS (java/others) Memory limit:32768/32768 K (java/others)
Total submission (s): 2372 Accepted Submission (s): 989
Problem DescriptionIn Zjnu, there is a well-known prairie. And it attracts pleasant sheep and his companions to has a holiday. Big Big Wolf and his families know on this, and quietly hid in the big lawn. As Zjnu ACM/ICPC team, we have a obligation to protect pleasant sheep and he companions to free from being disturbed by Big Big Wolf. We decided to build a number of unit fence whose length is 1. Any wolf and sheep can not cross the fence. Of course, one grid can only contain an animal.
Now, we ask for the minimum fences to let pleasant sheep and he companions to free from being disturbed by Big BIG W Olf and his companions.
Inputthere is many cases.
For every case:
N and M (n,m<=200)
Then N*m matrix:
0 is empty, and 1 are pleasant sheep and his companions, 2 are big Big Wolf and his companions.
Outputfor every case:
First line output ' case p: ', p is the p-th case;
The second line is the answer.
Sample Input
4 61 0 0 1 0 00 1 1 0 0 02 0 0 0 0 00 2 0 1 1 0
Sample Output
Case 1:4
Source2009 multi-university Training Contest 14-host by Zjnu
Test instructions: To a n*m of the giant, 1: For the Sheep, 2: To represent the wolf. Now use a 1-length fence to separate the wolves from the sheep and ask at least how many fences to use.
Problem solving: Minimum cut. Map: Source point s=0, Meeting Point t=n*m+1; The wolf is connected to the source, the edge capacity inf, the sheep and the meeting point are connected, the edge capacity INF. The other adjacent points are connected, and the contents is 1.
#include <stdio.h> #include <string.h> #include <queue>using namespace std; #define Captype Intconst int MAXN = 40010; Total number of points const int MAXM = 400010; Total number of edges const int INF = 1<<30;struct edg{int to,next; Captype Cap;} Edg[maxm];int Eid,head[maxn];int GAP[MAXN]; The number of points for each distance (or can be considered a height) int DIS[MAXN]; The shortest distance from each point to the end Enode int CUR[MAXN]; Cur[u] indicates that from the U point can flow through the cur[u] number side void init () {eid=0; memset (head,-1,sizeof (Head));} There are three parameters to the edge, 4 parameters void addedg (int u,int v,captype c,captype rc=0) without a forward edge {edg[eid].to=v; edg[eid].next=head[u]; Edg[eid].cap=c; head[u]=eid++; Edg[eid].to=u; EDG[EID].NEXT=HEAD[V]; EDG[EID].CAP=RC; head[v]=eid++;} Preprocessing Enode points to all points at the shortest distance void BFS (int sNode, int enode) {queue<int>q; memset (Gap,0,sizeof (GAP)); memset (dis,-1,sizeof (dis)); Gap[0]=1; dis[enode]=0; Q.push (Enode); while (!q.empty ()) {int U=q.front (); Q.pop (); for (int i=head[u]; i!=-1; i=edg[i].next) {int v=edg[i].to; if (dis[v]==-1) {dis[v]=dis[u]+1; gap[dis[v]]++; Q.push (v); }}}}int S[MAXN]; Path stack, which is the ID number of the edge captype maxflow_sap (int snode,int enode, int n) {//NOTE: N is the total number of points, including the source point and the meeting point BFS (SNode, Enode); Pre-Enode the shortest distance to all points if (dis[snode]==-1) return 0; Source point to unreachable sink point memcpy (cur,head,sizeof (head)); int top=0; Stack top Captype ans=0; Max Stream int U=snode; while (dis[snode]<n) {//determines from SNode point there is no flow to the next adjacent point if (u==enode) {//Find a way to add flow captype min=inf; int inser; for (int i=0; i<top; i++)//Find the maximum amount of traffic Min if (min>=edg[s[i]].cap) {min=edg[s[i]].c) from this flow-up path Ap Inser=i; } for (int i=0; i<top; i++) {edg[s[i]].cap-=min; Edg[s[i]^1].cap+=min; Flow of the side that can be recycled} ans+=min; Top=inser; From the flow of this can be added to the flow of the bottleneck in the edge of the upper edge of the flow can be increased, so only from the fault of the traffic bottleneck cutting u=edg[s[top]^1].to; Traffic Bottleneck EdgeThe starting point of continue; } bool flag = FALSE; It is possible to determine whether an int v can flow toward the neighboring point from the U point; for (int i=cur[u]; i!=-1; i=edg[i].next) {v=edg[i].to; if (edg[i].cap>0 && dis[u]==dis[v]+1) {flag=true; Cur[u]=i; Break }} if (flag) {s[top++] = Cur[u]; Add an edge u=v; Continue }//If a flow adjacent point is not found above, then the distance from the starting point U (which can also be considered a height) is the minimum distance of +1 int mind= n for the adjacent flow point; for (int i=head[u]; i!=-1; i=edg[i].next) if (edg[i].cap>0 && mind>dis[edg[i].to]) {Mind=dis [Edg[i].to]; Cur[u]=i; } gap[dis[u]]--; if (gap[dis[u]]==0) return ans; When Dis[u] The point of this distance is gone, it is impossible to find an augmented stream path from the source point//Because there is only one distance from the sink point to the current point, then from the source point to the sink point must pass the current point, but the current point is not able to find Can flow to the point, then the inevitable cut-off dis[u]=mind+1; If a flow adjacent point is found, the distance is the adjacent point distance of +1, or n+1 gap[dis[u]]++ if it is not found; if (U!=snode) u=edg[s[--top]^1].to; Return an Edge} return ans; int main () {int _cas=0,n,m,a; int dir[4][2]={0,1,0,-1,1,0,-1,0}; while (scanf ("%d%d", &n,&m) >0) {int s=0,t=n*m+1; Init (); for (int. i=0; i<n; i++) for (int j=0; j<m; J + +) {scanf ("%d", &a); if (a==2) addedg (S, i*m+j+1, INF); else if (a==1) addedg (i*m+j+1,t, INF); int TI,TJ; for (int e=0; e<4; e++) {ti=i+dir[e][0]; TJ=J+DIR[E][1]; if (ti>=0&&ti<n&&tj>=0&&tj<m) addedg (i*m+j+1,ti*m+tj+1, 1); }} printf ("Case%d:\n%d\n", ++_cas,maxflow_sap (S, T, t+1)); }}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
HDU 3046 pleasant sheep and Big big Wolf (min cut)