1. Floyd
//exam: B3647 【模板】Floyd
#include <iostream>
#include <cstring>
#include <cstdio>
#define int long long
using namespace std;
const int MAXN = 105;
int f[MAXN][MAXN];
int n, m;
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
memset(f, 0x3f, sizeof(f));
cin >> n >> m;
for(int i = 1; i <= n; i++) {
f[i][i] = 0;
}
for(int i = 1, u, v, w; i <= m; i++) {
cin >> u >> v >> w;
f[u][v] = f[v][u] = min(f[u][v], w);
}
for(int k = 1; k <= n; k++) {
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
}
}
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
cout << f[i][j] << " ";
}
cout << endl;
}
return 0;
}
2. Shortest Path Faster Algorithm
//exam: P3385 【模板】负环
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#define int long long
#define pii pair<int, int>
#define mk(x, y) make_pair(x, y)
#define fs first
#define sc second
using namespace std;
const int INF = 0x3f3f3f3f3f3f3f3f;
bool spfa();
vector< vector<pii> > g;
int t, n, m;
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> t;
while(t--) {
cin >> n >> m;
g.clear();
g.resize(n + 1);
for(int i = 1, u, v, w; i <= m; i++) {
cin >> u >> v >> w;
g[u].push_back(mk(v, w));
if(w >= 0) {
g[v].push_back(mk(u, w));
}
}
cout << (spfa() ? "YES" : "NO") << endl;
}
return 0;
}
bool spfa() {
queue<int> q;
vector<int> f, cnt;
vector<bool> book;
f.resize(n + 1, INF), cnt.resize(n + 1, 0);
book.resize(n + 1, false);
f[1] = 0;
q.push(1);
book[1] = true;
while(!q.empty()) {
int u = q.front(); q.pop();
book[u] = false;
cnt[u]++;
if(cnt[u] > n) {
return true;
}
for(auto e : g[u]) {
int v = e.fs, w = e.sc;
if(f[v] > f[u] + w) {
f[v] = f[u] + w;
if(!book[v]) {
book[v] = true;
q.push(v);
}
}
}
}
return false;
}
3. 线性筛
//exam:P3383 【模板】线性筛素数(线性筛)
#include <iostream>
#include <cstdio>
#include <cmath>
//#define int long long
using namespace std;
const int MAXN=2e8+5;
bool book[MAXN];
int a[MAXN],b[MAXN];
int n,q,m;
signed main(){
ios::sync_with_stdio(false);
cin>>n>>q;
for(int i=2;i<=n;i++){
if(!book[i]){
b[++m]=i;
}
for(int j=1;j<=m&&i*b[j]<=n;j++){
book[i*b[j]]=true;
if(i%b[j]==0){
break;
}
}
}
for(int i=1;i<=q;i++){
int x;
cin>>x;
cout<<b[x]<<endl;
}
return 0;
}
4. 树状数组
//exam:P3374 【模板】树状数组 1
#include <iostream>
#include <cstdio>
#define int long long
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int MAXN=5e5+5;
int query(int);
void update(int,int);
int n,m;
signed main(){
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1,u;i<=n;i++){
cin>>u;
update(i,u);
}
for(int i=1;i<=m;i++){
int k,u,v;
cin>>k>>u>>v;
if(k==1){
update(u,v);
}else{
cout<<query(v)-query(u-1)<<endl;
}
}
return 0;
}
int tree[MAXN];
int query(int x){
int res=0;
while(x){
res+=tree[x];
x-=lowbit(x);
}
return res;
}
void update(int x,int v){
while(x<=n){
tree[x]+=v;
x+=lowbit(x);
}
}
5. LCA
//exam:P3379 【模板】最近公共祖先(LCA)
#include <iostream>
#include <cstdio>
#include <vector>
#define int long long
using namespace std;
const int MAXN=5e5+5,MAXM=25;
void dfs(int,int);
int lca(int,int);
vector<int> g[MAXN];
int deep[MAXN];
int n,q,s;
signed main(){
cin>>n>>q>>s;
for(int i=1,u,v;i<n;i++){
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(s,0);
while(q--){
int a,b;
cin>>a>>b;
cout<<lca(a,b)<<endl;
}
return 0;
}
int f[MAXN][MAXM];
void dfs(int u,int fa){
f[u][0]=fa,deep[u]=deep[fa]+1;
for(int i=1;i<=20;i++){
f[u][i]=f[f[u][i-1]][i-1];
}
for(int i=0;i<g[u].size();i++){
int v=g[u][i];
if(v!=fa){
dfs(v,u);
}
}
}
int lca(int u,int v){
if(deep[u]<deep[v]){
swap(u,v);
}
int l=deep[u]-deep[v];
for(int i=0;i<=20;i++){
if(l&(1<<i)){
u=f[u][i];
}
}
if(u==v){
return u;
}
for(int i=20;i>=0;i--){
if(f[u][i]!=f[v][i]){
u=f[u][i],v=f[v][i];
}
}
return f[u][0];
}
6. Tarjan 缩点
//exam:P3387 【模板】缩点
/*
tarjan 缩点 + 拓扑求最大
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#define int long long
using namespace std;
const int MAXN=1e5+5;
bool check(int);
void tarjan(int);
void topsort();
vector<int> g[MAXN],G[MAXN];
int indeed[MAXN],belong[MAXN];
int a[MAXN],u[MAXN],v[MAXN];
int f[MAXN];
int n,m,ans;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=m;i++){
cin>>u[i]>>v[i];
g[u[i]].push_back(v[i]);
}
for(int i=1;i<=n;i++){
if(!check(i)){
tarjan(i);
}
}
for(int i=1;i<=m;i++){
int x=belong[u[i]],y=belong[v[i]];
if(x!=y){// 顶点不同
G[x].push_back(y);
indeed[y]++;
}
}
topsort();
for(int i=1;i<=n;i++){
ans=max(ans,f[i]);
}
cout<<ans;
return 0;
}
stack<int> s;
bool book[MAXN];
int low[MAXN],dfn[MAXN];
int scc[MAXN];// 节点在强连通分量中的编号
int len[MAXN];// 这个强连通分量的大小
int dfncnt,size;
bool check(int u){
return dfn[u];
}
void tarjan(int u){
low[u]=dfn[u]=++dfncnt;// 赋 dfs 序编号
s.push(u);
book[u]=true;// 在栈中
for(auto v:g[u]){
if(!dfn[v]){// 这个点没有遍历过
tarjan(v);
low[u]=min(low[u],low[v]);
}else if(book[v]){// 在栈中
low[u]=min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u]){// 强连通分量的起始点
++size;
while(true){
int t=s.top();s.pop();
scc[t]=size,book[t]=false;
belong[t]=u;// 链接点
len[size]++;
if(t==u){
break;
}
a[u]+=a[t];// 缩点
}
}
}
queue<int> q;
void topsort(){// 拓扑排序
for(int i=1;i<=n;i++){
if(i==belong[i]&&!indeed[i]){
q.push(i);
f[i]=a[i];
}
}
while(!q.empty()){
int u=q.front();q.pop();
for(auto v:G[u]){
f[v]=max(f[v],f[u]+a[v]);
indeed[v]--;
if(!indeed[v]){
q.push(v);
}
}
}
}