zoukankan      html  css  js  c++  java
  • hdu 3468 Treasure Hunting

    二分图匹配

    题意: 。。。 看了半天

    我们可以从rally点出发到最近的rally点, 如果有treasure在这两个rally点的最短路径上, 我们可以拿走他。

    思路也可以参见http://blog.csdn.net/wall_f/article/details/8990937

    这种分析问题的思路太值得学习了。。

    一开始没看懂题。。 在vj上找了个代码 (o(╯□╰)o。。 谴责一下自己。。)然后写了一下注释。。

    写完注释发现就那么回事 不想再敲一遍了。。噗。。

      1 /*Author :usedrose  */
      2 /*Created Time :2015/8/3 21:00:00*/
      3 /*File Name :2.cpp*/
      4 #pragma comment(linker, "/STACK:1024000000,1024000000") 
      5 #include <cstdio>
      6 #include <iostream>
      7 #include <algorithm>
      8 #include <sstream>
      9 #include <cstdlib>
     10 #include <cstring>
     11 #include <climits>
     12 #include <vector>
     13 #include <string>
     14 #include <ctime>
     15 #include <cmath>
     16 #include <deque>
     17 #include <queue>
     18 #include <stack>
     19 #include <set>
     20 #include <map>
     21 #define INF 0x3f3f3f3f
     22 #define eps 1e-8
     23 #define pi acos(-1.0)
     24 #define MAXN 1110
     25 #define MAXM 100110
     26 #define OK cout << "ok" << endl;
     27 #define o(a) cout << #a << " = " << a << endl
     28 #define o1(a,b) cout << #a << " = " << a << "  " << #b << " = " << b << endl
     29 using namespace std;
     30 typedef long long LL;
     31 
     32 int vv[MAXM], nxt[MAXM], h[MAXN*MAXN], e;
     33 char str[MAXN][MAXN];
     34 int n, m;
     35 int dis[55][MAXN*MAXN];
     36 int d[MAXN][MAXN];
     37 int bx[MAXN], by[MAXN];
     38 
     39 void addedge(int u,int v)
     40 {
     41     vv[e] = v;
     42     nxt[e] = h[u];
     43     h[u] = e++;
     44 }
     45 
     46 int vis[MAXN*MAXN], pre[MAXN*MAXN];
     47 int dx[] = {0, 0, 1, -1};
     48 int dy[] = {1, -1, 0, 0};
     49 
     50 int getid(char x)
     51 {
     52     if (isupper(x)) return x - 'A';
     53     if (islower(x)) return x - 'a' + 26;
     54     if (x == '*') return -1;
     55     return -2;
     56 }
     57 
     58 int getid(int x, int y)
     59 {
     60     return x*m + y;
     61 }
     62 
     63 bool inside(int x, int y)
     64 {
     65     return x >= 0 && x < n && y >= 0 && y < m;
     66 }
     67 
     68 
     69 void bfs(int x, int y)
     70 {
     71     queue<int> q;
     72     memset(d, -1, sizeof(d));
     73     q.push(x), q.push(y);
     74     d[x][y] = 0;
     75     while (!q.empty()) {
     76         x = q.front(); q.pop();
     77         y = q.front(); q.pop();
     78         for (int i = 0;i < 4; ++ i) {
     79             int x1 = x + dx[i];
     80             int y1 = y + dy[i];
     81             if (inside(x1, y1) && str[x1][y1] != '#' && d[x1][y1] < 0) {
     82                 d[x1][y1] = d[x][y] + 1;
     83                 q.push(x1); q.push(y1);
     84             }
     85         }
     86     }
     87 }
     88 
     89 bool init()
     90 {
     91     memset(bx, -1, sizeof(bx));
     92     for (int i = 0;i < n; ++ i)
     93         for (int j = 0;j < m;++ j) {
     94             int x = getid(str[i][j]); 
     95             if (x >= 0) {                // if it is a rally point
     96                 bx[x] = i, by[x] = j;     //note its position
     97                 bfs(i, j);                // get the shortest path around it
     98                 for (int k = 0;k < n; ++ k)
     99                     for (int l = 0;l < m; ++ l) {
    100                         dis[x][k*m+l] = d[k][l];    // get the distances from the point to all nodes
    101                         if (getid(str[k][l]) >= 0 && d[k][l] == -1) return false;// if unreachable 
    102                     }
    103             }
    104         }
    105     for (int i = 0;i < n; ++ i)
    106         for (int j = 0;j < m; ++ j) if (str[i][j] == '*') { // for all treasure
    107             for (int k = 1;bx[k] != -1; ++ k) {// for all rally points
    108                 if (dis[k-1][i*m+j] + dis[k][i*m+j] == dis[k-1][getid(bx[k],by[k])]) // if treasure on the shortest path between two rallys
    109                     if (dis[k-1][i*m+j] != -1 && dis[k][i*m+j] != -1)
    110                         addedge(k, i*m+j);            //we should add an edge
    111             }
    112         }
    113     return true;
    114 }
    115 
    116 int dfs(int u)
    117 {
    118     for (int i = h[u]; i + 1;i = nxt[i]) {
    119         int v = vv[i];
    120         if (vis[v]) continue;
    121         vis[v] = 1;
    122         if (pre[v] == -1 || dfs(pre[v])) {
    123             pre[v] = u;
    124             return 1;
    125         }
    126     }
    127     return 0;
    128 }
    129 
    130 int solve()
    131 {
    132     if (!init()) return -1;
    133     int ans = 0;
    134     memset(pre, -1, sizeof(pre));
    135     for (int i = 1; bx[i] != -1;++ i) {
    136         memset(vis, 0 ,sizeof(vis));
    137         ans += dfs(i);
    138     }
    139     return ans;
    140 }
    141 
    142 int main()
    143 {
    144     while (cin >> n >> m) {
    145         memset(h, -1, sizeof(h));
    146         e = 0;
    147         for (int i = 0;i < n; ++ i) 
    148             cin >> str[i];
    149         cout << solve() << endl;
    150     }
    151     return 0;
    152 }
  • 相关阅读:
    RubyConf的podcast
    一篇很好的英语学习文章:一个孤独而封闭世界――英语口语
    新浪和搜狐的读书频道
    新想法:个性化的RSS
    代码搜索:Koders
    我看到的Web 2.0: 自组织的大众化参与
    土豆网的后舍男孩挺搞笑的
    可以给pdf加批注的软件VeryPDF PDF Editor
    张海迪写的描写英语学习经验的书《美丽的英语》
    Fowler出来推荐Rake了(基于Ruby的build工具)
  • 原文地址:https://www.cnblogs.com/usedrosee/p/4700614.html
Copyright © 2011-2022 走看看