#include"6087.h"
using namespace std;
typedef vector<vector<vector<int>>> vvvi;
typedef vector<vector<char>> vvc;
typedef vector<vector<int>> vvi;
typedef vector<int> vi;
namespace
{
int w, h;
vvc tmap;
vvvi mcount;
vi sp = { -1,-1 };
vi tp;
vvi dirArr = { {1,0},{-1,0},{0,1},{0,-1} };
bool isValid(int i, int j)
{
return 0 <= i && i < h && 0 <= j && j < w;
}
// 0 1 > -1 0, 1 0
// 위아래로 가고 있었다면 좌우, 좌우면 위아래로
// 예외 : 좀 더 많은 거울을 지났더라도, 다른 방향이라면 최소일 경우 존재?
void bfs(int count, int i, int j, int dirIdx)
{
if (!isValid(i, j)) return;
if (tmap[i][j] == '*') return;
if (mcount[i][j][dirIdx] <= count) return;
mcount[i][j][dirIdx] = count;
if (i == tp[0] && j == tp[1]) return;
// 일단 가던 방향으로 보내보고
vi dir = dirArr[dirIdx];
bfs(count, i + dir[0], j + dir[1], dirIdx);
if (dir[0] == 0) // 좌우로 가고 있었다면 위아래로 바꾼다
{
dir = dirArr[0];
bfs(count + 1, i + dir[0], j + dir[1], 0);
dir = dirArr[1];
bfs(count + 1, i + dir[0], j + dir[1], 1);
}
else
{
dir = dirArr[2];
bfs(count + 1, i + dir[0], j + dir[1], 2);
dir = dirArr[3];
bfs(count + 1, i + dir[0], j + dir[1], 3);
}
}
}
void B6087::Solution()
{
cin >> w >> h;
tmap = vvc(h, vector<char>(w));
mcount = vvvi(h, vvi(w, vi(4,10001)));
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
cin >> tmap[i][j];
if (tmap[i][j] == 'C')
{
if (sp[0] == -1) sp = { i,j };
else tp = { i,j };
}
}
}
for (int idx=0; idx<4; idx++)
{
int newi = sp[0] + dirArr[idx][0];
int newj = sp[1] + dirArr[idx][1];
bfs(0, newi, newj, idx);
}
vi tpm = mcount[tp[0]][tp[1]];
cout << *min_element(tpm.begin(),tpm.end());
}
#include"6087.h"
using namespace std;
typedef vector<vector<vector<int>>> vvvi;
typedef vector<vector<char>> vvc;
typedef vector<vector<int>> vvi;
typedef vector<int> vi;
void B6087::Solution()
{
cin.tie(nullptr)->sync_with_stdio(false);
vi sp = { -1,-1 };
vi tp;
vvi dirArr = { {1,0},{-1,0},{0,1},{0,-1} };
int w, h;
cin >> w >> h;
vvc tmap = vvc(h, vector<char>(w));
vvvi mcount = vvvi(h, vvi(w, vi(4, 10001)));
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
cin >> tmap[i][j];
if (tmap[i][j] == 'C')
{
if (sp[0] == -1) sp = { i,j };
else tp = { i,j };
}
}
}
deque<vi> dq;
for (int idx : {0, 1, 2, 3})
{
mcount[sp[0]][sp[1]][idx] = 0;
vi dir = dirArr[idx];
dq.push_front({ sp[0],sp[1],idx });
}
while (!dq.empty())
{
int i = dq.front()[0];
int j = dq.front()[1];
int dirIdx = dq.front()[2];
vi dir = dirArr[dirIdx];
dq.pop_front();
for (int newDirIdx : {0, 1, 2, 3})
{
vi newDir = dirArr[newDirIdx];
int newi = i + newDir[0];
int newj = j + newDir[1];
if (newi < 0 || newj < 0 || h <= newi || w <= newj) continue;
if (tmap[newi][newj] == '*') continue;
int newCount = mcount[i][j][dirIdx] + 1;
if (dirIdx == newDirIdx) newCount--;
if (mcount[newi][newj][newDirIdx] <= newCount) continue;
mcount[newi][newj][newDirIdx] = newCount;
if (tmap[newi][newj] == 'C') continue;
if(dirIdx == newDirIdx) dq.push_front({newi,newj,dirIdx});
else dq.push_back({ newi,newj,newDirIdx });
}
}
vi tpm = mcount[tp[0]][tp[1]];
cout << *min_element(tpm.begin(), tpm.end());
}
(dir[0] == 0) ^ (newDir[0] == 0)로 수평인지 확인했었는데, 필요없었다. 같을 때 비용처리만 따로 하면 됨. 어차피 반대편으로 가는 건 비용 조건 때문에 걸러지기 때문.#include"1916.h"
using namespace std;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
void B1916::Solution()
{
int N, M, start, end, edgeCost;
cin >> N >> M;
vvvi g = vvvi(N+1);
vl cost = vl(N+1, 1000 * 100000);
while (M--)
{
cin >> start >> end >> edgeCost;
g[start].push_back({ edgeCost, end });
}
cin >> start >> end;
priority_queue<vl, vvl, greater<vl>> pq;
pq.push({0,start}); // 최종 비용, 도착점
cost[start] = 0;
// 정점 빼서 간선들 봤을 때 최솟값이 변경됐다면
// 거기서 다시 간선들 훑어서 최소 우선순위 큐에 넣어준다
while (!pq.empty())
{
ll d = pq.top()[0];
ll n = pq.top()[1];
pq.pop();
if (d != cost[n]) continue;
for (vi e : g[n])
{
if (d + e[0] >= cost[e[1]]) continue;
cost[e[1]] = d + e[0];
pq.push({ d + e[0], e[1] });
}
}
cout << cost[end];
}
풀긴했는데 또 시간이 안 좋아서 다시 풀기
#include<vector>
#include<iostream>
#include<queue>
#include<tuple>
using namespace std;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<vector<pii>> vvp;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, M, start, end, edgeCost;
cin >> N >> M;
vvp graph = vvp(N+1);
vi cost = vi(N + 1, 1000 * 100000);
while (M--)
{
cin >> start >> end >> edgeCost;
graph[start].push_back({ edgeCost, end });
}
cin >> start >> end;
priority_queue<pii, vector<pii>, greater<pii>> pq;
pq.push({ 0, start });
cost[start] = 0;
while (!pq.empty())
{
int dist, node;
tie(dist, node) = pq.top();
pq.pop();
if (dist != cost[node]) continue;
for (pii edge : graph[node])
{
int totalCost = edge.first + cost[node];
int nextNode = edge.second;
if (cost[nextNode] <= totalCost) continue;
cost[nextNode] = totalCost;
pq.push({ totalCost, nextNode });
}
}
cout << cost[end];
}
메모리도 시간도 남들처럼 나왔다
10^9라서, 10^5 * 10^3인 문제의 조건을 충분히 커버 가능앞으로 만들 기능들