最短路
1.单源bellman-ford
无圈,时间效率不高,边可以为负数
struct edge {
int from,to,cost;
} e[max_m];
int n,m; //n为点数,m为边数
int d[max_n];
for (int i=0;i<n;i++) dis[i]=inf;
d[start]=0;
while (true) {
bool f=false;
for (int i=0;i<m;i++) {
edge t=e[i];
if (d[t.from]!=inf && d[t.to]>d[t.from]+t.cost) {
d[t.to]=d[t.from]+t.cost;
f=true;
}
}
if (!f) break;
}
判断是否有负圈
bool f() {
memset(d,0,sizeof(d));
for (int i=0;i<n;i++) {
for (int j=0;j<m;j++) {
edge t=e[j];
if (d[t.to]>d[t.from]+t.cost) {
d[t.to]=d[t.from]+t.cost;
if (i==n-1) return true;
}
}
}
return false;
}
2.单源dijkstra
无法应用在有负边的情况
int cost[max_n][max_n],d[max_n];
bool used[max_n];
fill(d,d+n,inf);
fill(used,used+n,false);
d[start]=0;
while (true) {
int v=-1;
for (int i=0;i<n;i++) {
if (!used[i] && (v==-1 || d[i]<d[v])) v=i;
}
if (v==-1) break;
used[v]=true;
for (int i=0;i<n;i++)
d[i]=min(d[i],d[v]+cost[v][i]);
}
STL优先队列优化后
struct edge {
int to,cost;
};
vector<edge> e[max_n];
typedef pair<int,int> p; //first是最短距离,second是顶点编号
priority_queue<p,vector<p>,greater<p> > q;
int d[max_n];
fill(d,d+n,inf);
d[start]=0;
q.push(p(0,start));
while (!q.empty()) {
p pp=q.top();
q.pop();
int v=pp.second;
if (d[v]<pp.first) continue;
for (int i=0;i<e[v].size();i++) {
edge t=e[v][i];
if (d[t.to]>d[v]+t.cost) {
d[t.to]=d[v]+t.cost;
q.push(p(d[t.to],t.to));
}
}
}
3.任意两点间floyd_warshall
边可以为负数
int cost[max_n][max_n];
for (int k=0;k<n;k++) {
for (int i=0;i<n;i++) {
for (int j=0;j<n;j++)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
}
}
最小生成树
1.prim
int cost[max_n][max_n],mincost[max_n];
int sum=0;
bool used[max_n];
for (int i=0;i<n;i++) {
mincost[i]=inf;
used[i]=false;
}
mincost[0]=0;
while (true) {
int v=-1;
for (int i=0;i<n;i++) {
if (!used[i] && (v==-1 || mincost[i]<mincost[v])) v=u;
}
if (v==-1) break;
used[v]=true;
sum+=mincost[v];
for (int i=0;i<n;i++)
mincost[i]=min(mincost[i],cost[v][i]);
}
2.kruskal
struct edge {
int from,to,cost;
} e[max_m];
bool cmp(const edge& e1,const edge& e2) {
return e1.cost<e2.cost;
}
sort(e,e+m,cmp);
init_union_find(); //并查集
int sum=0;
for (int i=0;i<m;i++) {
edge t=e[i];
if (!same(t.from,t.to)) {
unite(t.from,t.to);
sum+=t.cost;
}
}