1.并查集
int par[MAX_N];
int rank[MAX_N];
void init(int n){
for(int i=0;i<n;i++){
par[i]=i;
rank[i]=0;
}
}
int find(int x){
if(par[x]==x){
return x;
}else{
return par[x]=find(par[x]);
}
}
void unite(int x,int y){
x=find(x);
y=find(y);
if(x==y) return;
if(rank[x]<rank[y]){
par[x]=y;
}else{
par[y]=x;
if(rank[x]==rank[y]) rank[x]++;
}
}
bool same(int x,int y){
return find(x)==find(y);
}
2.最短路
单源最短路——Bellman-Ford
struct edge{
int from,to,cost;
};
edge es[MAX_E];
int d[MAX_V];
int V,E;
void shortest_path(int s){
for(int i=0;i<V;i++) d[i]=INF;
d[s]=0;
while(true){
bool update=false;
for(int i=0;i<E;i++){
edge e=es[i];
if(d[e.from]!=INF&&d[e.to]>d[e.from]+e.cost){
d[e.to]=d[e.from]+e.cost;
update=true;
}
}
if(!update) break;
}
}
//返回true则存在负圈
bool find_negative_loop(){
memset(d,0,sizeof(d));
for(int i=0;i<V;i++){
for(int j=0;j<E;j++){
edge e=es[j];
if(d[e.to]>d[e.from]+e.cost){
d[e.to]=d[e.from]+e.cost;
if(i==V-1) return true;
}
}
}
return false;
}
单源最短路——Dijkstra
int cost[MAX_V][MAX_V];
int d[MAX_V];
bool used[MAX_V];
int V;
void dijkstra(int s){
fill(d,d+V,INF);
fill(used,used+V,false);
d[s]=0;
while(true){
int v=-1;
for(int u=0;u<V;u++){
if(!used[u]&&(v==-1||d[u]<d[v])) v=u;
}
if(v==-1) break;
used[v]=true;
for(int u=0;u<V;u++){
d[u]=min(d[u],d[v]+cost[v][u]);
}
}
}
单源最短路——Dijkstra(堆优化)
struct edge{
int to,cost;
};
typedef pair<int,int> P;
int V;
vector<edge> G[MAX_V];
int d[MAX_V];
void dijkstra(int s){
//按照p.first的小顶堆
priority_queue<P,vector<P>,greater<P> > que;
fill(d,d+V,INF);
d[s]=0;
que.push(P(0,s));
while(!que.empty()){
P p=que.top();
que.pop();
int v=p.second();
if(d[v]<p.first) continue;
for(int i=0;i<G[v].size();i++){
edge e=G[v][i];
if(d[e.to]>d[v]+e.cost){
d[e.to]=d[v]+e.cost;
que.push(P(d[e.to],e.to));
}
}
}
}
单源最短路——Floyd
for(int j=0;j<n;j++)
for(int i=0;i<n;i++)
for(int k=0;k<n;k++)
d[i][k]=min(d[i][k],d[i][j]+d[j][k]);
3.最小生成树
prim算法
int cost[MAX_V][MAX_V];
int mincost[MAX_V];
bool used[MAX_V];
int v;
int prim(){
for(int i=0;i<V;i++){
mincost[i]=INF;
used[i]=false;
}
mincost[0]=0;
int res=0;
while(true){
int v=-1;
for(int u=0;u<V;u++){
if(!used[u]&&(v==-1||mincost[u]<mincost[v])) v=u;
}
if(v==-1) break;
used[v]=true;
res+=mincost[v];
for(int u=0;u<V;u++){
mincost[u]=min(mincost[u],cost[v][u]);
}
}
return res;
}
kruskal算法
struct edge{
int u,v,cost;
};
bool comp(const edge& e1,const edge& e2){
return e1.cost<e2.cost;
}
edge es[MAX_E];
int V,E;
int kruskal(){
sort(es,es+E,comp);
init_union_find(V);
int res=0;
for(int i=0;i<E;i++){
edge e=es[i];
if(!same(e.u,e.v)){
unite(e.u,e.v);
res+=e.cost;
}
}
return res;
}