CSP前把重要的板子全部打一遍吧,顺便放一些下饭集锦(在每个板子的下面)
图论
SPFA
ll dis[N]; bool vis[N]; queue<int> q; void spfa(int s) { memset(vis,0,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); q.push(s);vis[s]=1;dis[s]=0; while(!q.empty()) { int u=q.front();q.pop();vis[u]=0; for(register int i=head[u];i;i=edge[i].next) { int v=edge[i].to; if(dis[v]>dis[u]+edge[i].dis) { dis[v]=dis[u]+edge[i].dis; if(!vis[v]) { q.push(v); vis[v]=1; } } } } }
注意事项:没什么好注意的,spfa极其优美,手感舒适
下饭集锦:v写成了edge[i].next
Dijkstra
struct Node { int u; ll dis; bool operator < (const Node &a) const { return a.dis<dis; } }; ll dis[N]; bool vis[N]; priority_queue<Node> q; void dijkstra(int s) { memset(vis,0,sizeof(vis)); memset(dis,0x7f,sizeof(dis)); q.push(Node{s,0});dis[s]=0; while(!q.empty()) { int u=q.top().u;q.pop(); if(vis[u]) continue; vis[u]=1; for(register int i=head[u];i;i=edge[i].next) { int v=edge[i].to; if(dis[v]>dis[u]+edge[i].dis) { dis[v]=dis[u]+edge[i].dis; q.push(Node{v,dis[v]}); } } } }
注意事项:第一个节点不要更新vis标记,在循环的时候再判断和更新;取出优先队列元素的时候也不用清空标记;自定义Node的时候别写反了……
下饭集锦:跑最短路,然后我写的大根堆……