hdu1733 需要多少时间逃出迷宫 :拆点/分层网络流
枚举时间来对于拆的点分层,每增加一个时间,就将所有1s能到达他的上个时间分层点->这个点的该时间分层点连一个边。
源点只向第1s的‘X’连边,所有'@'直接终点在任何时间都向汇点连边。
假设需要时间为ans,拆出来的点不包括源点汇点应该是ans*n*m*2点,为什么*2呢,因为每个除了'#'点拆成2个点,中间流量为1
刚开始直接枚举时间重新建图T了==于是我只在第1s时间建图,每次加边加流直到等于人数==
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 150005 8 #define maxm 200005 9 #define inf 0x3f3f3f3f 10 using namespace std; 11 struct Edge{ 12 int from,to,cap,flow; 13 }; 14 struct dian{ 15 int x,y; 16 }; 17 struct dinic{ 18 int s,t,n; 19 vector<Edge>edges; 20 vector<int>G[maxn]; 21 bool vis[maxn]; 22 int cur[maxn],d[maxn]; 23 void init(int _s,int _t,int _n){ 24 s=_s; t=_t; n=_n; 25 edges.clear(); 26 for (int i=0;i<=_n;i++) G[i].clear(); 27 } 28 void add(int from,int to,int cap){ 29 Edge e; 30 e.from=from; e.to=to; e.cap=cap; e.flow=0; 31 edges.push_back(e); 32 e.from=to; e.to=from; e.cap=0; e.flow=0; 33 edges.push_back(e); 34 int m=edges.size(); 35 G[from].push_back(m-2); G[to].push_back(m-1); 36 } 37 bool bfs(){ 38 memset(vis,0,sizeof(vis)); 39 queue<int>q; 40 q.push(s); d[s]=0; vis[s]=1; 41 while (!q.empty()){ 42 int x=q.front(); q.pop(); 43 for (int i=0;i<G[x].size();i++){ 44 Edge& e=edges[G[x][i]]; 45 if (!vis[e.to]&&e.cap>e.flow){ 46 vis[e.to]=1; 47 d[e.to]=d[x]+1; 48 q.push(e.to); 49 } 50 } 51 } 52 return vis[t]; 53 } 54 int dfs(int x,int a){ 55 if (x==t||a==0) return a; 56 int flow=0,f; 57 for (int& i=cur[x];i<G[x].size();i++){ 58 Edge& e=edges[G[x][i]]; 59 if (d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){ 60 e.flow+=f; 61 edges[G[x][i]^1].flow-=f; 62 flow+=f; 63 a-=f; 64 if (a==0) break; 65 } 66 } 67 return flow; 68 } 69 int maxflow(){ 70 int flow=0; 71 while (bfs()){ 72 memset(cur,0,sizeof(cur)); 73 flow+=dfs(s,inf); 74 } 75 return flow; 76 } 77 }g; 78 int xx[]={0,0,1,-1}; 79 int yy[]={1,-1,0,0}; 80 int vis[25][25],n,m; 81 char s[25][25]; 82 int bfs(int x,int y) 83 { 84 dian n1,n2; 85 queue<dian>q; 86 memset(vis,0,sizeof(vis)); 87 n1.x=x; n1.y=y; 88 vis[x][y]=1; q.push(n1); 89 while (!q.empty()){ 90 n1=q.front(); q.pop(); 91 if (s[n1.x][n1.y]=='@') return 1; 92 for (int i=0;i<4;i++){ 93 n2.x=n1.x+xx[i]; 94 n2.y=n1.y+yy[i]; 95 if (n2.x<0||n2.x>=n||n2.y<0||n2.y>=m) continue; 96 if (vis[n2.x][n2.y]||s[n2.x][n2.y]=='#') continue; 97 vis[n2.x][n2.y]=1; 98 q.push(n2); 99 } 100 } 101 return 0; 102 } 103 int makeg(int ans) 104 { 105 int i=ans,j,k,st,ed; 106 st=0; ed=256*n*m*2+1; 107 if (ans==1){ 108 g.init(st,ed,256*n*m*2+2); 109 for (j=0;j<n;j++) 110 for (k=0;k<m;k++){ 111 if (s[j][k]=='X') g.add(st,j*m+k+1,inf); 112 if (s[j][k]=='@') g.add(j*m+k+1+n*m,ed,inf); 113 if (s[j][k]!='#') g.add(j*m+k+1,j*m+k+1+n*m,1); 114 } 115 } 116 else{ 117 for (j=0;j<n;j++) 118 for (k=0;k<m;k++){ 119 if (s[j][k]!='#'){ 120 g.add((2*i-3)*n*m+j*m+k+1,(2*i-2)*n*m+j*m+k+1,1); 121 if (j-1>=0) 122 g.add((2*i-3)*n*m+(j-1)*m+k+1,(2*i-2)*n*m+j*m+k+1,1); 123 if (j+1<n) 124 g.add((2*i-3)*n*m+(j+1)*m+k+1,(2*i-2)*n*m+j*m+k+1,1); 125 if (k-1>=0) 126 g.add((2*i-3)*n*m+j*m+k,(2*i-2)*n*m+j*m+k+1,1); 127 if (k+1<m) 128 g.add((2*i-3)*n*m+j*m+k+2,(2*i-2)*n*m+j*m+k+1,1); 129 } 130 if (s[j][k]=='@') g.add((2*i-1)*n*m+j*m+k+1,ed,inf); 131 if (s[j][k]!='#') 132 g.add((2*i-2)*n*m+j*m+k+1,(2*i-1)*n*m+j*m+k+1,1); 133 } 134 } 135 return g.maxflow(); 136 } 137 int main() 138 { 139 int c,flag,i,j,ans; 140 while (~scanf("%d%d",&n,&m)){ 141 c=0; flag=1; 142 for (i=0;i<n;i++){ 143 scanf("%s",s[i]); 144 for (j=0;j<m;j++) 145 if (s[i][j]=='X') c++; 146 } 147 for (i=0;i<n;i++) 148 for (j=0;j<m;j++) 149 if (s[i][j]=='X'&&!bfs(i,j)) flag=0; 150 if (!flag) {printf("-1\n"); continue; } 151 int tmp=0; 152 for (ans=1;;ans++){ 153 tmp+=makeg(ans); 154 if (tmp==c) break; 155 } 156 printf("%d\n",ans-1); 157 } 158 return 0; 159 }