二、图论

2.1 图的存储

2.1.1 邻接表

head[i]//起点为点i的边号
nxt[i]//i边的下一条边
to[i]//i边指向的点

add(a, b):
to[E] = b;
nxt[E] = head[a];
head[a] = E;
E++;

2.1.2 并查集

int Find(int x){
    int p, tmp;
    p = x;
    while(x != pre[x])
        x = pre[x];
    while(p != x){
        tmp = pre[x];
        pre[x] = x;
        p = tmp;
    }
    return x;
}

void join(int x, int y){
    int fx = Find(x);
    int fy = Find(y);
    if(fx != fy)
        pre[fx] = fy;
}
 
bool Same(int x, int y){
    return Find(x) == Find(y);
}
//状态压缩
int Find(int x){
    while(x != pre[x]){
        pre[x] = pre[pre[x]];
        x = pre[x];
    }
    return x;
}

2.2最短路径

2.2.1 五行算法——Floyd-Warshall

for(int k = 1; k <= n; k++){
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            //if(e[i][j] > e[i][k] + e[k][j] && e[i][k] < inf && e[k][j] < inf)
            if(e[i][j] > e[i][k] + e[k][j]){
                e[i][j] = e[i][k] + e[k][j];
            }
        }
    }
}

2.2.2Dijkstra——单源最短路

for(int i = 1; i <= n-1; i++){
	//找到离1号最近的点
	min = inf;
	for(int j = 1; j <= n; j++){
		if(book[j] == 0 && dis[j] < min){
			min = dis[j];
			u = j;
		}
	}
	book[u] = 1;
	for(int v = 1; v <= n; v++){
		if(e[u][v] < inf){
			if(dis[v] > dis[u] + e[u][v]){
				dis[v] = dis[u] + e[u][v];
			}
		}
	}
}

2.2.3 Bellman-Ford——解决负边权问题

for(int k = 1; k <= n-1; k++){
    for(int i = 1; i <= m; i++){
        if(dis[v[i]] > dis[u[i]] + w[i]){
            dis[v[i]] = dis[u[i]] + w[i];
        }
    }
}
没有未来的未来不是我想要的未来
原文地址:https://www.cnblogs.com/Little-Turtle--QJY/p/13898975.html