Codeforces Round #420 (Div. 2) D. Okabe and City (最短路)

来源:互联网 发布:淘宝订单号后四位意义 编辑:程序博客网 时间:2024/05/29 18:54

终于下定决心要写博客了,希望自己能坚持下去。


题意:n*m的方格里有k个方格是亮着的。主角要从(1,1)走到(n,m),只能走亮的格子。每次主角可以用一个硬币点亮一行或者一列的格子,但点亮下一行或下一列的时候,上次点亮的效果会消失。而且,改变点亮的行和列的时候,必须站在原来就亮着的格子。求最少支付的硬币数,无解输出-1。

做法很简单,除正常的建图之外,把每一行和一列都看成一个点,相邻的亮着的格子到这个点建两条有向边,格子到行列权是1,行列到格子权是0。跑一遍最短路即可。

现场SB了。。赛后再写很快就1A。

#include <bits/stdc++.h>using namespace std;#define endl '\n'#define INF 0x3f3f3f3fLLtypedef pair< int, int > pii;typedef long long ll;int encode(int x, int y){ return x * 100000 + y; }void decode(int a, int& x, int& y) { x = a / 100000; y = a % 100000; }set<int>s;map<int, int>mp;int now = 0;vector<int>v[100005];vector<int>c[100005];const int stepx[4] = {1,0,-1,0};const int stepy[4] = {0,1,0,-1};int n, m, k;int dis[100005];bool vis[100005];queue<int>q;bool check(int x, int y){    if (x >= 1 && x <= n && y >= 1 && y <= m) return 1;    else return 0;}int main(){    ios::sync_with_stdio(0);    cin >> n >> m >> k;    int S = -1, T = -1;    for (int i = 0; i < k; i++){        int x, y; cin >> x >> y;        s.insert(encode(x, y));        if (x == 1 && y == 1) S = now;        if (x == n && y == m) T = now;        mp[encode(x, y)] = now++;    }    int rowstart = now - 1;    int colstart = now + n - 1;    for (set<int>::iterator it = s.begin(); it != s.end(); it++){        int x, y; decode(*it, x, y);        for (int i = 0; i < 4; i++){            int newx = x + stepx[i];            int newy = y + stepy[i];            if (check(newx, newy) && s.find(encode(newx, newy)) != s.end()){                v[mp[encode(newx, newy)]].push_back(mp[*it]);                c[mp[encode(newx, newy)]].push_back(0);                v[mp[*it]].push_back(mp[encode(newx, newy)]);                c[mp[*it]].push_back(0);            }        }        for (int i = max(1, x - 1); i <= min(n, x + 1); i++){            v[rowstart + i].push_back(mp[*it]);            c[rowstart + i].push_back(0);            v[mp[*it]].push_back(rowstart + i);            c[mp[*it]].push_back(1);        }        for (int i = max(1, y - 1); i <= min(m, y + 1); i++){            v[colstart + i].push_back(mp[*it]);            c[colstart + i].push_back(0);            v[mp[*it]].push_back(colstart + i);            c[mp[*it]].push_back(1);        }    }    for (int i = 0; i < 100005; i++) {vis[i] = 0; dis[i] = INF;}    dis[S] = 0; q.push(S);    while (!q.empty()){        int now = q.front(); q.pop();        vis[now] = 0;        for (int i = 0; i < v[now].size(); i++){            if (dis[v[now][i]] > dis[now] + c[now][i]){                dis[v[now][i]] = dis[now] + c[now][i];                if (!vis[v[now][i]]){                    q.push(v[now][i]); vis[v[now][i]] = 1;                }            }        }    }    int ans = INF;    if (T != -1) ans = dis[T];    else ans = min(dis[rowstart + n], dis[colstart + m]);    if (ans == INF) ans = -1;    cout << ans << endl;    return 0;}


阅读全文
1 0
原创粉丝点击