1.并查集
for(int i=1;i<=n;i++){
fa[i]=i;
}//初始化
int find(int x){
if(fa[x]!=x){
fa[x]=find(fa[x]);
}
return fa[x];
}//find father,这里用了路径压缩
void merger(int x,int y){
if(find(x)!=find(y)){
fa[x]=y;
}
}
2.各种高精(普及同模之后几乎没有了)
getline(cin,a);
getline(cin,b);
if(a.size()>b.size()){
b=string((a.size()-b.size()),0)+b;
}else{
a=string(b.size()-a.size(),0)+a;
}
c='0'+a;
for(int i=a.size()-1;i>=0;i--){
c[i+1]=a[i]-'0'+b[i]-'0';
//c[i+1]=a[i]-'0'-(b[i]-'0');
}
for(int i=a.size()-1;i>=0;i--){
if(c[i]>=10){
c[i+1]=c[i]/10;
c[i]=c[i]%10;
}
//if(c[i]<0){
// c[i]=c[i]+10;
// c[i-1]=c[i]-1;
//}
}
3.归并排序(求逆序对)不断递归分解然后回的时候排序
void merger(int l,int mid,int r){
int i=s;int j=mid+1;
int k=s;
while(i<=mid&&j<=r){
if(a[i]>a[j]){
zancun[k++]=a[j++];
ans=mid-i+1;//从小到大排序,后面一定比他当前大
}else{
zancun[k++]=a[i++];
}
}
while(i<=mid){
zancun[k++]=a[i++];
}
while(j<=r){
zancun[k++]=a[j++];
}
for(int i=l;i<=r;i++){
a[i]=zancun[i];
}
}
void fen(int l,int r){
if(l<=r){
mid=(l+r)>>1;
fen(l,mid);
fen(mid+1,r);
merger(l,mid,r);
}
}
4.二分答案最大值最小等问题一定可以用二分降复杂度
void check(int k){
if(k满足条件){
return true;
}else{
return false;
}
}
int erfen(int l,int r){
int ans;
while(l<=r){
int mid=(l+r)/2;
if(check(mid)){
ans=check(mid);
l=mid+1;
}else{
r=mid;
}
}
return ans;
}
5.链式前向星(他有一个优秀的性质在存双向边时,i^1就是令一条边)
struct node{
int to;
int next;
};
node edge[maxn*2];
int head[maxn];
int ecnt;
void add(int x,int y){
edge[++ecnt].to=y;
edge[ecnt].next=head[x];
head[x]=ecnt;
}//这是最基础的,如果有需要还可以node里加信息,
6.快速幂基于二进制求一个数的幂,后面数论很多要用到他;
int ans=0;
while(b){
if(b&1==1){
ans=ans*a%m;
}
a=a*a%m;
b=b/2;
}
7.拓扑(将入度为0加入queue并且不断删点以更新入度)拓扑的括号化定里以后会在lca用到
queue<int>que;
int into[maxn];//入度
for(int i=1;i<=n;i++){
if(into[i]==0){
que.push(i);
}
}
while(que.size()!=0){
int x=que.top();
for(int i=head[x];i;i=edge[i].next){
int v=edge[i].to;
into[v]--;
if(into[v]==0){
que.push(v);
}
}
}
8.最短路--全源最短路floyd其基本思想是利用每个点去松弛每条边,更深理解见P1119 灾后重建
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][k]+f[k][j],f[i][j])
}
}
}
8.最短路--全源最短路johnson几乎用不到大体就是一遍spfa一遍dijkstra(几乎用不到)
#include<bits/stdc++.h>
using namespace std;
const long long maxn=1e9;
struct xing{
int from;
int to;
int w;
};
struct node{
int id;
int dist;
node(){
}
node(int nid,int ndist){
id=nid;
dist=ndist;
}
bool friend operator < (node a,node b){
return a.dist>b.dist;
}
};
priority_queue<node>pque;
int n,m,a,b,c;
xing xx[20009];
int head[20009],t[20009];
int flag[20009];
int ecnt;
long long h[20009],dist[20009];
bool spfa(int s){
queue<int>q;
memset(h,0x3f,sizeof(h));
h[s]=0;
flag[s]=1;
q.push(s);
while(q.size()!=0){
int now=q.front();
q.pop();
flag[now]=0;
for(int j=head[now];j;j=xx[j].from){
int v=xx[j].to;
if(h[v]>h[now]+xx[j].w){
h[v]=h[now]+xx[j].w;
if(flag[v]==0){
flag[v]=1;
q.push(v);
t[v]++;
if(t[v]==n+1){
return false;
}
}
}
}
}
return true;
}
void dijkstra(int s){
for(int i=1;i<=n;i++){
dist[i]=maxn;
}
memset(flag,0,sizeof(flag));
pque.push(node(s,0));
dist[s]=0;
while(pque.size()!=0){
int now=pque.top().id;
pque.pop();
if(flag[now]==1)continue;
flag[now]=1;
for(int j=head[now];j;j=xx[j].from){
int v=xx[j].to;
if(dist[v]>dist[now]+xx[j].w){
dist[v]=dist[now]+xx[j].w;
if(flag[v]==0){
pque.push(node(v,dist[v]));
}
}
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>a>>b>>c;
xx[++ecnt].to=b;
xx[ecnt].from=head[a];
xx[ecnt].w=c;
head[a]=ecnt;
}
for(int i=1;i<=n;i++){
a=0;
b=i;
c=0;
xx[++ecnt].to=b;
xx[ecnt].from=head[a];
xx[ecnt].w=c;
head[a]=ecnt;
}
if(spfa(0)==false){
cout<<-1<<endl;
return 0;
}
for(int i=1;i<=n;i++){
for(int j=head[i];j;j=xx[j].from){
xx[j].w+=h[i]-h[xx[j].to];
}
}
for(int i=1;i<=n;i++){
dijkstra(i);
long long ans=0;
for(int j=1;j<=n;j++){
if(dist[j]==maxn){
ans+=j*maxn;
}else{
ans+=j*(dist[j]+h[j]-h[i]);
}
}
cout<<ans<<endl;
}
}
9.dijlstra
struct xing{
int to;
int next;
int w;
};
xing xx[2*maxn];
int head[maxn];
int cnt;
void add(int x,int y,int val){
xing[++cnt].to=y;
xing[cnt].next=head[x];
xing[cnt].w=val;
head[x]=cnt;
}
struct node{
int from;
int to;
int val;
node(){
}
node(int nfrom,int nto,int nval){
from=nfrom;
to=nto;
val=nval;
}
bool friend operator < (node a,node b){
return a.val>b.val;
}
};
priority<node>pque;
int dist[maxn];
int flag[maxn];
void dijkstra(){
pque.push(ks);
dist[ks]=0;
while(pque.size()!=0){
int now=pque.top();
pque.pop();
if(flag[now]==1){
continue;
}
flag[now]=1;
for(int i=head[now];i;i=edge[i].next){
int v=edge[i].to;
if(dits[v]>dist[now]+edge[i].val){
dist[v]=dist[now]+edge[i].val;
pque.push(v);
}
}
}
}
10.spfa(判断负环)
queue<int>que;
int n;
bool spfa(){
dist[s]=0;
vis[s]=1;
que.push(s);
while(que.size()!=0){
int now=que.front();
que.pop();
for(int i=head[now];i;i=edge[i].next){
v=edge[i].to;
val=edge[i].val;
if(dist[v]>dis[now]+val){
dist[v]=dis[now]+val
cnt[v]=cnt[now]+1;
if(cnt[v]>=n)return false;
if(!vis[v]){
que.push(v);
vis[v]=true;
}
}
}
}
return true;
}
11.最小生成树.prim类似于dijkstra两种均是贪心
void prim(){
flag[s]=1;
pque.push(node(0,s,0));
while(pque.size()!=0){
int now=pque.top();
pque.pop();
if(flag[now]==1){
continue;
}
flag[now]=1;
for(int i=head[now];i;i=edge[i].next){
v=edge[i].to;
if(flag[v]==0){
pque.push(node(now,v,edge[i].val));
}
}
}
}
12.kruskal并查集加sort
int find(int x){
if(fa[x]!=x){
fa[x]=find(fa[x]);
}
return fa[x];
}
void kruskal(){
sort(edge+1,edge+1+m);
for(int i=1;i<=n;i++){
fa[i]=i;
}
for(int i=1;i<=m;i++){
int a=edge[i].from;
int b=edge[i].to;
if(find(a)!=find(b)){
fa[a]=b;
ans.push("这一条边");
ecnt++;
if(ecnt==n-1){
break;//一个树只有n-1边,so到了n-1直接break
}
}else{
continue;
}
}
}