1. 程式人生 > 實用技巧 >二、圖論

二、圖論

2.1 圖的儲存

2.1.1 並查集

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);
}

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];
        }
    }
}