题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36707
思路:根据题意拆点建图即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 #define MAXN 2222 8 #define inf 1<<30 9 10 struct Edge{ 11 int v,cap,next; 12 }edge[MAXN*MAXN]; 13 14 int n,m,p,NE,NV,vs,vt; 15 int head[MAXN]; 16 17 void Insert(int u,int v,int cap) 18 { 19 edge[NE].v=v; 20 edge[NE].cap=cap; 21 edge[NE].next=head[u]; 22 head[u]=NE++; 23 24 edge[NE].v=u; 25 edge[NE].cap=0; 26 edge[NE].next=head[v]; 27 head[v]=NE++; 28 } 29 30 int level[MAXN],gap[MAXN]; 31 void bfs(int vt) 32 { 33 memset(level,-1,sizeof(level)); 34 memset(gap,0,sizeof(gap)); 35 level[vt]=0; 36 gap[0]++; 37 queue<int>que; 38 que.push(vt); 39 while(!que.empty()){ 40 int u=que.front(); 41 que.pop(); 42 for(int i=head[u];i!=-1;i=edge[i].next){ 43 int v=edge[i].v; 44 if(level[v]!=-1)continue; 45 level[v]=level[u]+1; 46 gap[level[v]]++; 47 que.push(v); 48 } 49 } 50 } 51 52 int cur[MAXN],pre[MAXN]; 53 int SAP(int vs,int vt) 54 { 55 bfs(vt); 56 memset(pre,-1,sizeof(pre)); 57 memcpy(cur,head,sizeof(head)); 58 int u=pre[vs]=vs,aug=inf,maxflow=0; 59 gap[0]=NV; 60 while(level[vs]<NV){ 61 bool flag=false; 62 for(int &i=cur[u];i!=-1;i=edge[i].next){ 63 int v=edge[i].v; 64 if(edge[i].cap>0&&level[u]==level[v]+1){ 65 flag=true; 66 aug=min(aug,edge[i].cap); 67 pre[v]=u; 68 u=v; 69 if(v==vt){ 70 maxflow+=aug; 71 for(u=pre[u];v!=vs;v=u,u=pre[u]){ 72 edge[cur[u]].cap-=aug; 73 edge[cur[u]^1].cap+=aug; 74 } 75 aug=inf; 76 } 77 break; 78 } 79 } 80 if(flag)continue; 81 int minlevel=NV; 82 for(int i=head[u];i!=-1;i=edge[i].next){ 83 int v=edge[i].v; 84 if(edge[i].cap>0&&level[v]<minlevel){ 85 minlevel=level[v]; 86 cur[u]=i; 87 } 88 } 89 if(--gap[level[u]]==0)break; 90 level[u]=minlevel+1; 91 gap[level[u]]++; 92 u=pre[u]; 93 } 94 return maxflow; 95 } 96 97 char map[44][44]; 98 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; 99 100 int main() 101 { 102 while(~scanf("%d%d%d",&n,&m,&p)){ 103 for(int i=0;i<n;i++)scanf("%s",map[i]); 104 NE=0; 105 vs=0,vt=2*n*m+1,NV=2*n*m+2; 106 memset(head,-1,sizeof(head)); 107 for(int i=0;i<n;i++){ 108 for(int j=0;j<m;j++){ 109 if(map[i][j]=='~')continue; 110 for(int k=0;k<4;k++){ 111 int x=i+dir[k][0],y=j+dir[k][1]; 112 if(x<0||x>=n||y<0||y>=m)continue; 113 Insert(i*m+j+1+n*m,x*m+y+1,inf); 114 } 115 if(map[i][j]=='*'){ 116 Insert(vs,i*m+j+1,1); 117 Insert(i*m+j+1,i*m+j+1+n*m,1); 118 } 119 else if(map[i][j]=='.')Insert(i*m+j+1,i*m+j+1+n*m,1); 120 else if(map[i][j]=='@')Insert(i*m+j+1,i*m+j+1+n*m,inf); 121 else if(map[i][j]=='#')Insert(i*m+j+1,i*m+j+1+n*m,inf),Insert(i*m+j+1+n*m,vt,p); 122 } 123 } 124 printf("%d\n",SAP(vs,vt)); 125 } 126 return 0; 127 }