Codeforces821D Okabe and City(思维建图+最短路运用)
来源:互联网 发布:mac系统怎么剪切文件 编辑:程序博客网 时间:2024/06/05 21:38
题目链接:
http://codeforces.com/contest/821/problem/D
题目大意:
现在给你N*M的一个矩阵,现在上边一共有K个永恒亮着的点,主人公从左上角出发,走到的点必须有亮光才行。
但是现在不保证有亮光的点能够使得主人公到达右下角,所以他可以花费1单位金币去使得一行或者一列暂时性的亮着,如果他想再次使用魔法,那么之前暂时亮着的部分就必须灭掉了。
问他最少花费多少金币,能够从左上角走到右下角。
如果不能走到,输出-1.
分析:
这题可以将k个点看做图中的点,由于站在一个初始亮的点上可以将一行或一列变亮,所以我们可以在这个点上,点亮相邻的一行或一列,然后再到相邻行列上的任意点,或者点亮这个点所在的行或列。这样就能够想到了再引入行和列作为图中的点,然后以k个点和相邻的行和列作为图的顶点建图。从一个点到相邻行列花费是1,反向花费是0,然后跑一遍最短路就可以了。
总结:灵活抽象运用最短路的好题!
具体实现请看代码:
#include<bits/stdc++.h>using namespace std;#define pii pair<int, int>const int maxn = 1e6+5;const int INF = 0x3f3f3f3f;pii p[maxn];map<pii, int> mp;struct edge{ int to, cost; edge(){} edge(int to, int cost):to(to), cost(cost){}};vector<edge> G[maxn];int nx[5] = {1, -1, 0, 0};int ny[5] = {0, 0, 1, -1};int dis[maxn];bool vis[maxn];void dijkstra(int s){ priority_queue<pii, vector<pii>, greater<pii> > q; memset(dis, 63, sizeof(dis)); memset(vis, false, sizeof(vis)); dis[s] = 0; q.push(pii(0, s)); while(!q.empty()) { pii tem = q.top(); q.pop(); int v = tem.second; if(vis[v]) continue;// if(dis[v] < tem.second) continue; vis[v] = true; for(int i = 0; i < G[v].size(); i++) { edge e = G[v][i]; if(dis[e.to] > dis[v] + e.cost) { dis[e.to] = dis[v] + e.cost; q.push(pii(dis[e.to], e.to)); } } }}int main(){ int n, m, k; scanf("%d%d%d", &n, &m, &k); mp.clear(); int dd = 1e4+5; for(int i = 1; i <= k; i++) { int r, c; scanf("%d%d", &r, &c); //从点到相邻边 G[i].push_back(edge(r+dd, 1)); G[i].push_back(edge(c+dd*2, 1)); G[i].push_back(edge(r+dd+1, 1)); G[i].push_back(edge(r+dd-1, 1)); G[i].push_back(edge(c+dd*2+1, 1)); G[i].push_back(edge(c+dd*2-1, 1)); //从相邻边到点 G[r+dd].push_back(edge(i, 0)); G[c+dd*2].push_back(edge(i, 0)); G[r+dd-1].push_back(edge(i, 0)); G[r+dd+1].push_back(edge(i, 0)); G[c+dd*2+1].push_back(edge(i, 0)); G[c+dd*2-1].push_back(edge(i, 0)); p[i] = pii(r, c); mp[p[i]] = i; } for(int i = 1; i <= k; i++) for(int j = 0; j < 4; j++) { int x = p[i].first + nx[j]; int y = p[i].second + ny[j]; //相邻点 if(mp.find(pii(x, y)) != mp.end()) G[i].push_back(edge(mp[pii(x, y)], 0)); } if(mp.find(pii(n, m)) == mp.end()) { G[n+dd].push_back(edge(k+1, 0)); G[m+dd*2].push_back(edge(k+1, 0)); } dijkstra(mp[pii(1, 1)]); int ans; if(mp.find(pii(n, m)) == mp.end()) ans = dis[k+1]; else ans = dis[mp[pii(n, m)]]; if(ans == INF) ans = -1; printf("%d\n", ans); return 0;}
阅读全文
0 0
- Codeforces821D Okabe and City(思维建图+最短路运用)
- D. Okabe and City codeforces 最短路
- Codeforces 821D Okabe And City 最短路
- Codeforces 821D Okabe and City (拆点+思维建图+spfa)
- Codeforces Round #420 (Div. 2) 821D Okabe and City 思维建图+dij
- Codeforces Round #420 (Div. 2) 821D Okabe and City 思维建图+spfa
- Codeforces Round #420 (Div. 2) D. Okabe and City (最短路)
- Codeforces Round #420 (Div. 2) D. Okabe and City(最短路)
- Codeforces Round #420 (Div. 2) D. Okabe and City 最短路
- Codeforces Round #420 (Div. 2) D. Okabe and City(最短路)
- Codeforces 821D Okabe and City【思维建图+Dij+优先队列优化】好题~好题~
- Codeforces 821 D. Okabe and City
- Codeforces 821D Okabe and City 题解
- codeforces 821d Okabe and City
- CF 821D Okabe and City
- 最短路 思维导图
- Codeforces Round #420 (Div. 2) 821D Okabe and City
- CF-Codeforces Round #420 (Div. 2)-D-Okabe and City
- C陷阱与缺陷第一章 词法“陷阱”
- 根据中序、前序(后序)输出树的后序(前序),不重建树
- 【CJOJ2500】【DP合集】背包 bound
- 深度学习新星:GAN的基本原理、应用和走向
- 游戏自评——英雄无敌手游
- Codeforces821D Okabe and City(思维建图+最短路运用)
- think in java第九章接口 总结随笔
- 升级win10 系统后80 端口被占用 问题排查、解决
- win10+anaconda+pycharm使用tensorflow
- Matlab作图之全框坐标轴
- 常用控件2
- 一个简单的单线程OJ判题端(java实现)
- 从零构建一个灰度发布环境(二)系统配置
- JAVA二进制详解