1.分段
#include<iostream>
#include<cmath>
using namespace std;
int aSubscriber[200002] = { 0 };
int L[450], R[450];
int pos[200002];
int sumK[450];
int maxK[450];
int minK[450];
void init(int N, int mSubscriber[]) {
aSubscriber[0] = 0;
for (int i = 0; i < N; i++)
{
pos[i] = 0;
aSubscriber[i + 1] = mSubscriber[i];
}
for (int i = 1; i <450; i++)
{
maxK[i] = -1;
minK[i] = 10001;
sumK[i] = 0;
L[i] = 0;
R[i] = 0;
}
int t = sqrt(N*1.0);
int num = N / t;
if (N%t)
{
num++;
}
for (int i = 1; i <= num; i++)
{
L[i] = (i - 1)*t + 1;
R[i] = i * t;
}
R[num] = N;
for ( int i = 1; i <=num; i++)
{
for (int j = L[i]; j <= R[i]; j++)
{
pos[j] = i;
sumK[i] += aSubscriber[j];
if (minK[i] > aSubscriber[j])
{
minK[i] = aSubscriber[j];
}
if (maxK[i] < aSubscriber[j])
{
maxK[i] = aSubscriber[j];
}
}
}
return;
}
int updateKuai(int mId)
{
int kuai = pos[mId];
minK[kuai] = 10001;
maxK[kuai] = -1;
for (int j = L[kuai]; j <= R[kuai]; j++)
{
if (minK[kuai] > aSubscriber[j])
{
minK[kuai] = aSubscriber[j];
}
if (maxK[kuai] < aSubscriber[j])
{
maxK[kuai] = aSubscriber[j];
}
}
return kuai;
}
int subscribe(int mId, int mNum) {
aSubscriber[mId] += mNum;
int kuai = updateKuai(mId);
sumK[kuai] += mNum;
return aSubscriber[mId];
}
int unsubscribe(int mId, int mNum) {
aSubscriber[mId] -= mNum;
int kuai = updateKuai(mId);
sumK[kuai] -= mNum;
return aSubscriber[mId];
}
int count(int sId, int eId) {
int res = 0;
int kuais = pos[sId];
int kuaie = pos[eId];
if (kuais == kuaie)
{
for (int i = sId; i <= eId; i++)
{
res += aSubscriber[i];
}
}
else
{
for (int i = kuais + 1; i <= kuaie - 1; i++)
{
res += sumK[i];
}
for (int i = sId; i <= R[kuais]; i++)
{
res += aSubscriber[i];
}
for (int i = L[kuaie]; i <=eId; i++)
{
res += aSubscriber[i];
}
}
return res;
}
int calculate(int sId, int eId) {
int res = 0;
int kuais = pos[sId];
int kuaie = pos[eId];
int min = 10001, max = -1;
if (kuais == kuaie)
{
for (int i = sId; i <= eId; i++)
{
if (min > aSubscriber[i])
{
min = aSubscriber[i];
}
if (max < aSubscriber[i])
{
max = aSubscriber[i];
}
}
res = max - min;
}
else
{
for (int i = kuais + 1; i <= kuaie - 1; i++)
{
if (min > minK[i])
{
min = minK[i];
}
if (max < maxK[i])
{
max = maxK[i];
}
}
for (int i = sId; i <= R[kuais]; i++)
{
if (min > aSubscriber[i])
{
min = aSubscriber[i];
}
if (max < aSubscriber[i])
{
max = aSubscriber[i];
}
}
for (int i = L[kuaie]; i <= eId; i++)
{
if (min > aSubscriber[i])
{
min = aSubscriber[i];
}
if (max < aSubscriber[i])
{
max = aSubscriber[i];
}
}
res = max - min;
}
return res;
}
2.迪杰斯特拉
#include<bits/stdc++.h>
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
int INF = 0x3f3f3f3f;
const int MAXN = 20;
bool visit[MAXN];
int mDis[MAXN];
int mPrev[MAXN];
struct point {
int vec, dis;
point(int v, int d)
{
vec = v;
dis = d;
}
bool operator < (const point &other)const {
if (dis != other.dis)
{
return dis > other.dis;
}
}
};
vector <point> Graph[MAXN];
void djs(int start)
{
memset(mPrev, -1, sizeof(mPrev));
memset(visit, false, sizeof(visit));
memset(mDis, INF, sizeof(mDis));
mDis[start] = 0;
mPrev[start] = start;
priority_queue<point> q;
q.push({ start,0 });
while (!q.empty())
{
point temp = q.top();
int midV = temp.vec;
int midD = temp.dis;
q.pop();
if (visit[midV])
{
continue;
}
visit[midV] = true;
for (int i = 0; i < Graph[midV].size(); i++)
{
int eV = Graph[midV][i].vec;
int eD = Graph[midV][i].dis;
if (!visit[eV] && eD + mDis[midV] < mDis[eV])
{
mDis[eV] = eD + mDis[midV];
mPrev[eV] = midV;
q.push({ eV,mDis[eV] });
}
}
}
}
void initEdge() {
for (int u = 0; u < MAXN; u++)
{
for (int v = 0; v < MAXN; v++)
{
if (u == v)
{
Graph[u].push_back({ v, 0 });
Graph[v].push_back({ u, 0 });
}
if (u != v)
{
Graph[u].push_back({ v, INF });
Graph[v].push_back({ u, INF });
}
}
}
}
void addEdge(int u, int v, int w) {
Graph[u].push_back({ v, w });
}
void printShortestPaths(int start) {
cout << "Shortest paths from node " << start << ":" << endl;
for (int i = 0; i < MAXN; ++i) {
if (mDis[i] != INF) {
cout << "Distance to node " << i << ": " << mDis[i] << endl;
}
else {
cout << "Node " << i << " is unreachable from node " << start << endl;
}
}
}
void printPath(int start, int end) {
if (mPrev[end] == -1) {
cout << "No path from " << start << " to " << end << endl;
return;
}
vector<int> path;
for (int v = end; v != start; v = mPrev[v]) {
path.push_back(v);
}
path.push_back(start);
reverse(path.begin(), path.end());
cout << "Path from " << start << " to " << end << ": ";
for (size_t i = 0; i < path.size(); ++i) {
cout << path[i];
if (i < path.size() - 1) cout << " -> ";
}
cout << endl;
}
int main() {
initEdge();
addEdge(0, 1, 3);
addEdge(0, 2, 1);
addEdge(0, 3, 5);
addEdge(1, 2, 2);
addEdge(1, 3, 4);
addEdge(1, 4, 1);
addEdge(2, 4, 6);
addEdge(3, 4, 2);
djs(0);
printShortestPaths(0);
for (int i = 0; i < 5; i++)
{
printPath(0, i);
}
return 0;
}
vector<pair<int, int>> g[500005];
int dis[500005];
void dijkstra(int s)
{
memset(dis, 0x3f3f3f3f, sizeof(dis));
dis[s] = 0;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
q.push({ 0, s });
while (!q.empty())
{
pair<int, int> p = q.top();
q.pop();
int u = p.second;
int d = p.first;
if (dis[u] < d) continue;
for (int i = 0; i < g[u].size(); i++)
{
int v = g[u][i].second;
int w = g[u][i].first;
if (dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
q.push({ dis[v], v });
}
}
}
}
int main()
{
int n, m;
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++)
{
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
g[u].push_back({ w, v });
g[v].push_back({ w, u });
}
dijkstra(1);
for (int i = 1; i <= n; i++)
{
printf("%d ", dis[i]);
}
}
3.BFS+DJS
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define MAX_MAP_SIZE 350
#define MAXMAPSIZE 355
#define MAXGATENUM 205
#define INF 0x3f3f3f3f
int gN = 0;
int cnt = 0;
int HP = 0;
int mp[MAXMAPSIZE][MAXMAPSIZE];
int isRemoved[MAXGATENUM];
struct node
{
int r;
int c;
int dis;
};
int visited[MAXMAPSIZE][MAXMAPSIZE];
int dx[] = { 1,-1,0,0 };
int dy[] = { 0,0,1,-1 };
int edge[MAXGATENUM][MAXGATENUM];
node positions[MAXGATENUM];
node MyQueue[MAXMAPSIZE*MAXMAPSIZE + 1];
void bfsMyQueue(int mGateID, int mRow, int mCol)
{
memset(visited, 0, sizeof(visited));
int head = 0, tail = 0;
MyQueue[tail].r = mRow;
MyQueue[tail].c = mCol;
MyQueue[tail++].dis = 0;
while (head < tail)
{
int curDis = MyQueue[head].dis;
int row = MyQueue[head].r;
int col = MyQueue[head++].c;
if (curDis >= HP)
{
break;
}
for (int i = 0; i < 4; i++)
{
int tx = row + dx[i];
int ty = col + dy[i];
if (tx < 0 || tx > gN - 1 || ty < 0 || ty > gN - 1)
{
continue;
}
if (mp[tx][ty] == 1 || visited[tx][ty] == 1)
{
continue;
}
visited[tx][ty] = 1;
if (mp[tx][ty] > 1)
{
int gateNum = mp[tx][ty] / 10;
edge[gateNum][mGateID] = curDis + 1;
edge[mGateID][gateNum] = curDis + 1;
}
MyQueue[tail].r = tx;
MyQueue[tail].c = ty;
MyQueue[tail++].dis = curDis + 1;
}
}
}
queue <node> STLQueue;
void bfsSTLQueue(int mGateID, int mRow, int mCol)
{
memset(visited, 0, sizeof(visited));
while (!STLQueue.empty())
{
STLQueue.pop();
}
STLQueue.push({ mRow,mCol,0 });
while (!STLQueue.empty())
{
node t = STLQueue.front();
STLQueue.pop();
if (t.dis >= HP)
{
break;
}
for (int i = 0; i < 4; i++)
{
int x = t.r + dx[i];
int y = t.c + dy[i];
int d = t.dis + 1;
if (x >= 0 && x < gN && y >= 0 && y < gN && !visited[x][y]
&& mp[x][y] != 1 && mp[x][y] != -1)
{
visited[x][y] = 1;
STLQueue.push({ x,y,d });
if (mp[x][y] > 1)
{
int gateNum = mp[x][y] / 10;
edge[gateNum][mGateID] = d;
edge[mGateID][gateNum] = d;
}
}
}
}
}
void removeGate(int mGateID)
{
int x = positions[mGateID].r;
int y = positions[mGateID].c;
mp[x][y] = 0;
isRemoved[mGateID] = 1;
}
struct dijNode
{
int id;
int dist;
bool operator < (dijNode z) const
{
return dist > z.dist;
}
};
int Dist[MAXGATENUM];
bool djsVisit[MAXGATENUM];
void dijstrak(int startID, int endID)
{
memset(Dist, INF, sizeof(Dist));
memset(djsVisit, false, sizeof(djsVisit));
Dist[startID] = 0;
priority_queue <dijNode> myPQ;
myPQ.push({ startID,0 });
while (!myPQ.empty())
{
dijNode t = myPQ.top();
int midV = t.id;
int midD = t.dist;
myPQ.pop();
if (midV == endID)
{
return;
}
if (djsVisit[midV])
{
continue;
}
djsVisit[midV] = true;
for (int i = 1; i <= cnt; i++)
{
if (isRemoved[i])continue;
if (Dist[i] > midD + edge[midV][i])
{
Dist[i] = midD + edge[midV][i];
myPQ.push({ i,Dist[i] });
}
}
}
}
void init(int N, int mMaxStamina, int mMap[MAX_MAP_SIZE][MAX_MAP_SIZE])
{
gN = N;
cnt = 0;
HP = mMaxStamina;
memset(mp, -1, sizeof(mp));
memset(edge, INF, sizeof(edge));
memset(isRemoved, 0, sizeof(isRemoved));
memset(positions, -1, sizeof(positions));
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
mp[i][j] = mMap[i][j];
}
}
}
void addGate(int mGateID, int mRow, int mCol)
{
cnt++;
mp[mRow][mCol] = mGateID * 10;
edge[mGateID][mGateID] = 0;
positions[mGateID].r = mRow;
positions[mGateID].c = mCol;
bfsSTLQueue(mGateID, mRow, mCol);
}
int getMinTime(int mStartGateID, int mEndGateID)
{
if (edge[mStartGateID][mEndGateID] != INF)
{
return edge[mStartGateID][mEndGateID];
}
dijstrak(mStartGateID, mEndGateID);
if (Dist[mEndGateID] != INF)
{
return Dist[mEndGateID];
}
return -1;
}
4.hash
#include <unordered_map>
using namespace std;
#define MAX_SIZE 1000
#define TILE_SIZE 5
unordered_map<int, int> tile_hash_table;
int tile_type_id;
int counter[MAX_SIZE * MAX_SIZE / (TILE_SIZE * TILE_SIZE)];
int up_left_most_position[MAX_SIZE * MAX_SIZE / (TILE_SIZE * TILE_SIZE)];
int tile_data[TILE_SIZE][TILE_SIZE];
int(*position_plane)[MAX_SIZE];
int add_tile(int data[5][5], int row, int col) {
int hash_code = 0;
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 5; ++j) {
hash_code = hash_code * 2 + data[i][j];
}
if (tile_hash_table.find(hash_code) != tile_hash_table.end()) {
int type = tile_hash_table[hash_code];
++counter[type];
return type;
}
tile_hash_table[hash_code] = tile_type_id;
hash_code = 0;
for (int j = 0; j <= 4; j++)
{
for (int i = 4; i >= 0; i--)
{
hash_code = hash_code * 2 + data[i][j];
}
}
tile_hash_table[hash_code] = tile_type_id;
hash_code = 0;
for (int i = 4; i >= 0; i--)
{
for (int j = 4; j >= 0; j--)
{
hash_code = hash_code * 2 + data[i][j];
}
}
tile_hash_table[hash_code] = tile_type_id;
hash_code = 0;
for (int j = 4; j >= 0; j--)
{
for (int i = 0; i <= 4; i++)
{
hash_code = hash_code * 2 + data[i][j];
}
}
tile_hash_table[hash_code] = tile_type_id;
up_left_most_position[tile_type_id] = (row + 2) * 10000 + (col + 2);
counter[tile_type_id] = 1;
return tile_type_id++;
}
void init(int N, int mPlane[MAX_SIZE][MAX_SIZE]) {
tile_hash_table = unordered_map<int, int>();
tile_type_id = 0;
position_plane = mPlane;
for (int y = 0; y < N - 4; ++y) {
for (int x = 0; x < N - 4; ++x) {
if (mPlane[y][x] > 1) {
x += 4;
continue;
}
int star = 0;
for (int i = y; i < y + 5; ++i)
for (int j = x; j < x + 5; ++j)
star += mPlane[i][j];
if (star == 7) {
for (int i = y; i < y + 5; ++i)
for (int j = x; j < x + 5; ++j) {
tile_data[i - y][j - x] = mPlane[i][j];
}
int type = add_tile(tile_data, y, x);
for (int i = y; i < y + 5; ++i)
for (int j = x; j < x + 5; ++j)
position_plane[i][j] = up_left_most_position[type];
x += 4;
}
}
}
}
int getCount(int mPiece[5][5]) {
int hash_code = 0;
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 5; ++j) {
hash_code = hash_code * 2 + mPiece[i][j];
}
if (tile_hash_table.find(hash_code) != tile_hash_table.end())
{
int type = tile_hash_table[hash_code];
return counter[type];
}
return 0;
}
int getPosition(int mRow, int mCol) {
return position_plane[mRow][mCol];
}
二分
#include <queue>
using namespace std;
#define MAX_N 10001
#define MAX_POP 1000
#define f __attribute((optimize("Ofast")))
int population[MAX_N];
int travelTime[MAX_N];
int lanes[MAX_N];
int n;
struct pairr {
int time;
int ids;
bool operator < (const pairr& other)const {
if (time != other.time)
return time < other.time;
if (ids != other.ids)
{
return ids > other.ids;
}
}
};
struct comp {
bool operator()(pairr& a, pairr& b)const {
if (a.time == b.time)
return a.ids > b.ids;
return a.time < b.time;
}
};
priority_queue<pairr> pq;
f void init(int N, int mPopulation[])
{
n = N;
pq = {};
for (register int i = 0; i < N; i++)
population[i] = mPopulation[i];
for (register int i = 0; i < N - 1; i++) {
lanes[i] = 1;
travelTime[i] = population[i] + population[i + 1];
pq.push({ travelTime[i], i });
}
return;
}
f int expand(int M)
{
int lastTime;
while (M--) {
pairr temp = pq.top();
pq.pop();
int id = temp.ids;
lanes[id]++;
travelTime[id] = (population[id] + population[id + 1]) / lanes[id];
pq.push({ travelTime[id], id });
lastTime = travelTime[id];
}
return lastTime;
}
f int calculate(int mFrom, int mTo)
{
int sum = 0;
if (mFrom > mTo) swap(mFrom, mTo);
for (register int i = mFrom; i < mTo; i++)
sum += travelTime[i];
return sum;
}
f inline bool isPossible(int mFrom, int mTo, int K, int mid) {
int sum = 0, cnt = 1;
for (register int i = mFrom; i <= mTo; i++) {
if (cnt > K) return false;
sum += population[i];
if (sum > mid) {
cnt += 1;
sum = population[i];
}
}
if (cnt > K) return false;
return true;
}
f int divide(int mFrom, int mTo, int K)
{
int low = 0, high = (mTo - mFrom + 1) * MAX_POP;
int res = -1;
while (low < high) {
int mid = low + (high - low) / 2;
if (isPossible(mFrom, mTo, K, mid)) {
high = mid;
}
else low = mid + 1;
}
return high;
}
djs 变种 Spot Travel
#include<iostream>
#include<vector>
#include<queue>
#include<climits>
using namespace std;
#define WALK 0
#define BIKE 1
#define TAXI 2
vector<pair<int, int>> adj[101];
bool hasCycleStand[101];
int n;
struct Travel {
int spot;
int time;
int cost;
int mode;
};
void init(int N)
{
n = N;
for (int i = 0; i < 101; i++) {
hasCycleStand[i] = 0;
adj[i].clear();
}
}
void addRoad(int K, int mSpotA[], int mSpotB[], int mDis[])
{
for (int i = 0; i < K; i++) {
adj[mSpotA[i]].push_back({ mSpotB[i], mDis[i] });
adj[mSpotB[i]].push_back({ mSpotA[i], mDis[i] });
}
}
void addBikeRent(int mSpot)
{
hasCycleStand[mSpot] = 1;
}
struct cmp {
bool operator()(const Travel& a, const Travel& b) const {
return a.cost == b.cost ? a.time > b.time : a.cost > b.cost;
}
};
int getMinMoney(int mStartSpot, int mEndSpot, int mMaxTime)
{
int dist[101][3];
int time[101][3];
priority_queue<Travel, vector<Travel>, cmp> pq;
for (int i = 0; i < 101; i++) {
for (int j = 0; j < 3; j++) {
dist[i][j] = INT_MAX;
time[i][j] = INT_MAX;
}
}
pq.push({ mStartSpot, 0, 0, WALK });
for (int i = 0; i < 3; i++) {
dist[mStartSpot][i] = 0;
time[mStartSpot][i] = 0;
}
while (!pq.empty()) {
Travel travel = pq.top();
pq.pop();
if (travel.time > mMaxTime) {
continue;
}
if (travel.cost > dist[travel.spot][travel.mode] && travel.time > time[travel.spot][travel.mode]) {
continue;
}
if (travel.spot == mEndSpot) {
if (travel.mode != BIKE || hasCycleStand[travel.spot])
return travel.cost;
}
dist[travel.spot][travel.mode] = min(travel.cost, dist[travel.spot][travel.mode]);
time[travel.spot][travel.mode] = min(travel.time, time[travel.spot][travel.mode]);
for (auto& it : adj[travel.spot]) {
int next = it.first;
int dis = it.second;
if (travel.mode == WALK) {
pq.push({ next, travel.time + 17 * dis, travel.cost, WALK });
if (hasCycleStand[travel.spot])
pq.push({ next, travel.time + 4 * dis, travel.cost + 4 * dis, BIKE });
pq.push({ next, travel.time + dis + 7, travel.cost + 19 * dis, TAXI });
}
else if (travel.mode == BIKE) {
if (!hasCycleStand[travel.spot]) {
pq.push({ next, travel.time + 4 * dis, travel.cost + 4 * dis, BIKE });
}
else {
pq.push({ next, travel.time + 17 * dis, travel.cost, WALK });
pq.push({ next, travel.time + 4 * dis, travel.cost + 4 * dis, BIKE });
pq.push({ next, travel.time + dis + 7, travel.cost + 19 * dis, TAXI });
}
}
else {
pq.push({ next, travel.time + 17 * dis, travel.cost, WALK });
if (hasCycleStand[travel.spot])
pq.push({ next, travel.time + 4 * dis, travel.cost + 4 * dis, BIKE });
pq.push({ next, travel.time + dis, travel.cost + 19 * dis, TAXI });
}
}
}
return -1;
}