hdu2732 拆点最大流/dinic
看题意看了半天你敢信===
L代表几只蜥蜴的初始位置,一次可以跳到距离<=d的柱子上(曼哈顿距离),柱子最多被跳过次数一定,问最多跳走多少蜥蜴
看懂题意就比较简单的拆点建图了,细节要注意
建边:
起点到有高度柱子连边,1
柱子向拆点柱子连边,x
拆点柱子向可跳跃柱子连边,inf
拆点柱子如果可以跳到终点向终点连边,inf
输出要注意==
1 #pragma comment(linker,"/STACK:16777216") 2 #include<stdio.h> 3 #include<string.h> 4 #include<queue> 5 #include<vector> 6 #include<algorithm> 7 #define maxn 100005 8 #define maxm 200005 9 #define inf 0x3f3f3f3f 10 using namespace std; 11 struct Edge{ 12 int from,to,cap,flow; 13 }; 14 struct dinic{ 15 int s,t,n; 16 vector<Edge>edges; 17 vector<int>G[maxn]; 18 bool vis[maxn]; 19 int cur[maxn],d[maxn]; 20 void init(int _s,int _t,int _n){ 21 s=_s; t=_t; n=_n; 22 edges.clear(); 23 for (int i=0;i<=_n;i++) G[i].clear(); 24 } 25 void add(int from,int to,int cap){ 26 Edge e; 27 e.from=from; e.to=to; e.cap=cap; e.flow=0; 28 edges.push_back(e); 29 e.from=to; e.to=from; e.cap=0; e.flow=0; 30 edges.push_back(e); 31 int m=edges.size(); 32 G[from].push_back(m-2); G[to].push_back(m-1); 33 } 34 bool bfs(){ 35 memset(vis,0,sizeof(vis)); 36 queue<int>q; 37 q.push(s); d[s]=0; vis[s]=1; 38 while (!q.empty()){ 39 int x=q.front(); q.pop(); 40 for (int i=0;i<G[x].size();i++){ 41 Edge& e=edges[G[x][i]]; 42 if (!vis[e.to]&&e.cap>e.flow){ 43 vis[e.to]=1; 44 d[e.to]=d[x]+1; 45 q.push(e.to); 46 } 47 } 48 } 49 return vis[t]; 50 } 51 int dfs(int x,int a){ 52 if (x==t||a==0) return a; 53 int flow=0,f; 54 for (int& i=cur[x];i<G[x].size();i++){ 55 Edge& e=edges[G[x][i]]; 56 if (d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){ 57 e.flow+=f; 58 edges[G[x][i]^1].flow-=f; 59 flow+=f; 60 a-=f; 61 if (a==0) break; 62 } 63 } 64 return flow; 65 } 66 int maxflow(){ 67 int flow=0; 68 while (bfs()){ 69 memset(cur,0,sizeof(cur)); 70 flow+=dfs(s,inf); 71 } 72 return flow; 73 } 74 }g; 75 char mp1[25][25],mp2[25][25]; 76 int main() 77 { 78 int T,t,n,m,d,ans,i,j,x,y; 79 scanf("%d",&T); 80 for (t=1;t<=T;t++){ 81 scanf("%d%d",&n,&d); 82 for (i=1;i<=n;i++) scanf("%s",mp1[i]); 83 for (i=1;i<=n;i++) scanf("%s",mp2[i]); 84 m=strlen(mp1[1]); 85 ans=0; 86 g.init(0,2*n*m+1,2*n*m+2); 87 for (i=1;i<=n;i++) 88 for (j=0;j<m;j++) 89 if (mp2[i][j]=='L'){ 90 ans++; 91 g.add(0,(i-1)*m+j+1,1); 92 } 93 for (i=1;i<=n;i++) 94 for (j=0;j<m;j++) 95 if (mp1[i][j]!='0'){ 96 g.add((i-1)*m+j+1,(i-1)*m+j+1+n*m,mp1[i][j]-'0'); 97 for (x=1;x<=n;x++) 98 for (y=0;y<m;y++) 99 if (mp1[x][y]!='0'&&abs(i-x)+abs(j-y)<=d&&(i!=x||j!=y)) 100 g.add((i-1)*m+j+1+n*m,(x-1)*m+y+1,inf); 101 if (i<=d||j+1<=d||i+d>n||j+d>=m) 102 g.add((i-1)*m+j+1+n*m,2*n*m+1,inf); 103 } 104 ans=ans-g.maxflow(); 105 printf("Case #%d: ",t); 106 if (ans==0) printf("no lizard was"); 107 else if (ans==1) printf("1 lizard was"); 108 else printf("%d lizards were",ans); 109 printf(" left behind.\n"); 110 } 111 return 0; 112 }