• POJ 3057 网络流 Evacuation


    题意:

    有一个n×m的房间,四周每个格子要么是墙要么是门。中间部分是墙或者人。

    现在所有人要从房间逃出去,每个人的速度为1,也就是每个单位时间只能向上下左右四个方向走一格。

    多个人可以站在同一个格子上,但是每个时刻每个门只能通过一格人,求所有人从房间中逃出去所需要的最少时间。

    分析:

    把每个人看成一个点,然后把每个时刻和门组成的二元组看成一个点。

    如果两点之间连一条边表示这个人在这个时刻从这个门逃出去。

    所以我们可以从小到大将时间逐渐加1,直到找到最大匹配为止。

    在增加点的时候,可以在之前最大流基础上增广,这样更快。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <vector>
      6 #include <queue>
      7 #include <map>
      8 #define MP make_pair
      9 using namespace std;
     10 
     11 typedef pair<int, int> PII;
     12 
     13 const int INF = 0x3f3f3f3f;
     14 const int maxh = 15;
     15 const int maxnode = 20000;
     16 
     17 char maze[maxh][maxh];
     18 int id[maxh][maxh];
     19 
     20 int row, col;
     21 
     22 vector<PII> people, doors;
     23 
     24 int dx[] = { 1, 0, -1, 0 };
     25 int dy[] = { 0, 1, 0, -1 };
     26 
     27 int dist[50][130];  //the distance from every door to people
     28 int steps[maxh][maxh];
     29 
     30 bool inline in(int x, int y) { return x >= 0 && x < row && y >= 0 && y < col; }
     31 
     32 bool vis[maxh][maxh];
     33 
     34 void bfs(PII s)
     35 {
     36     int st = id[s.first][s.second];
     37     steps[s.first][s.second] = 0;
     38     queue<PII> Q;
     39     Q.push(s);
     40     memset(vis, false, sizeof(vis));
     41     vis[s.first][s.second] = true;
     42 
     43     while(!Q.empty())
     44     {
     45         PII t = Q.front(); Q.pop();
     46         for(int i = 0; i < 4; i++)
     47         {
     48             int x = t.first + dx[i];
     49             int y = t.second + dy[i];
     50             if(in(x, y) && !vis[x][y] && maze[x][y] == '.')
     51             {
     52                 vis[x][y] = true;
     53                 dist[st][id[x][y]] = steps[x][y] = steps[t.first][t.second] + 1;
     54                 Q.push(MP(x, y));
     55             }
     56         }
     57     }
     58 }
     59 
     60 struct Edge
     61 {
     62     int from, to, cap, flow;
     63     Edge(int u, int v, int c, int f):from(u), to(v), cap(c), flow(f) {}
     64 };
     65 
     66 int nodes;
     67 vector<int> G[maxnode];
     68 vector<Edge> edges;
     69 
     70 void init()
     71 {
     72     edges.clear();
     73     for(int i = 0; i < nodes; i++) G[i].clear();
     74 }
     75 
     76 void AddEdge(int u, int v, int cap)
     77 {
     78     edges.push_back(Edge(u, v, cap, 0));
     79     edges.push_back(Edge(v, u, 0, 0));
     80     int m = edges.size();
     81     G[u].push_back(m - 2);
     82     G[v].push_back(m - 1);
     83 }
     84 
     85 int s, t;
     86 bool visit[maxnode];
     87 int d[maxnode], cur[maxnode];
     88 
     89 bool BFS()
     90 {
     91     memset(visit, false, sizeof(visit));
     92     queue<int> Q;
     93     Q.push(s);
     94     d[s] = 0;
     95     visit[s] = true;
     96 
     97     while(!Q.empty())
     98     {
     99         int u = Q.front(); Q.pop();
    100         for(int i = 0; i < G[u].size(); i++)
    101         {
    102             Edge& e = edges[G[u][i]];
    103             int v = e.to;
    104             if(!visit[v] && e.cap > e.flow)
    105             {
    106                 visit[v] = true;
    107                 Q.push(v);
    108                 d[v] = d[u] + 1;
    109             }
    110         }
    111     }
    112 
    113     return visit[t];
    114 }
    115 
    116 int DFS(int u, int a)
    117 {
    118     if(u == t || a == 0) return a;
    119     int flow = 0, f;
    120     for(int& i = cur[u]; i < G[u].size(); i++)
    121     {
    122         Edge& e = edges[G[u][i]];
    123         int v = e.to;
    124         if(d[v] == d[u] + 1 && (f = DFS(v, min(a, e.cap - e.flow))) > 0)
    125         {
    126             e.flow += f;
    127             edges[G[u][i]^1].flow -= f;
    128             flow += f;
    129             a -= f;
    130             if(a == 0) break;
    131         }
    132     }
    133     return flow;
    134 }
    135 
    136 int Maxflow()
    137 {
    138     int flow = 0;
    139     while(BFS())
    140     {
    141         memset(cur, 0, sizeof(cur));
    142         flow += DFS(s, INF);
    143     }
    144     return flow;
    145 }
    146 
    147 void Readuce()
    148 {
    149     for(int i = 0; i < edges.size(); i++)
    150         edges[i].cap -= edges[i].flow, edges[i].flow = 0;
    151 }
    152 
    153 int main()
    154 {
    155     int T; scanf("%d", &T);
    156     while(T--)
    157     {
    158         scanf("%d%d", &row, &col);
    159         for(int i = 0; i < row; i++) scanf("%s", maze[i]);
    160 
    161         memset(id, 0, sizeof(id));
    162         people.clear(); doors.clear();
    163         int psz = 0, dsz = 0;
    164         for(int i = 0; i < row; i++)
    165             for(int j = 0; j < col; j++)
    166             {
    167                 if(maze[i][j] == 'D') { doors.push_back(MP(i, j)); id[i][j] = dsz++; }
    168                 else if(maze[i][j] == '.') { people.push_back(MP(i, j)); id[i][j] = psz++; }
    169             }
    170 
    171         memset(dist, 0x3f, sizeof(dist));
    172         for(int i = 0; i < dsz; i++) bfs(doors[i]);
    173         bool unreachable = false;
    174         for(int i = 0; i < psz; i++)
    175         {
    176             bool reach = false;
    177             for(int j = 0; j < dsz; j++)
    178                 if(dist[j][i] < INF) { reach = true; break; }
    179             if(reach == false) { unreachable = true; break; }
    180         }
    181 
    182         if(unreachable) { puts("impossible"); continue; }
    183 
    184         int tot_time = 0;
    185         s = 0, t = 1;
    186         nodes = 2 + psz;
    187         init();
    188         for(int i = 0; i < psz; i++) AddEdge(s, i + 2, 1);
    189 
    190         int matches = 0;
    191         for(;;)
    192         {
    193             tot_time++;
    194             for(int i = 0; i < dsz; i++)
    195             {
    196                 G[nodes].clear();
    197                 AddEdge(nodes, t, 1);
    198                 for(int j = 0; j < psz; j++)
    199                     if(dist[i][j] <= tot_time) AddEdge(j + 2, nodes, 1);
    200                 nodes++;
    201             }
    202             matches += Maxflow();
    203             if(matches == psz) break;
    204             Readuce();
    205         }
    206         printf("%d
    ", tot_time);
    207     }
    208 
    209     return 0;
    210 }
    代码君
  • 相关阅读:
    VB.Net计算含日文的字符串长度
    修改三个属性,就可以让错误提示更详细
    ORACLE分页查询SQL语法
    探知主力仓位的原理
    Linux手机研发五大难关
    当SNS在垂直行业嫁接电子商务
    实时股票数据获取方式
    商业周刊:网民周末更爱移动Web 分类信息超社交
    Linux下的C编程实战
    想起了赵丹阳
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4793200.html
Copyright © 2020-2023  润新知