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 }
View Code

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1733

posted on 2015-04-28 01:10  xiao_xin  阅读(167)  评论(0编辑  收藏  举报

导航