pat必刷模板第十章 图

图的遍历

                        //图
                         
						                                    //dfs遍历(模板)
dfs(u){//访问顶点u(只能访问一个连通分量) 
	vis[u] = true;//设置u已被访问 
	for(从u出发能到达的所有顶点v)//枚举u出发可以到达的所有顶点v
	    if vis[v] == false;
		    dfs(v);//递归v 
}						
dfstrave(g){//遍历图g 
	for(g的所有顶点u)//对g的所有顶点u 
	    if vis[u] == false;//如果未被访问 
		    dfs[u]; //访问u所在的连通分量 
} 
 								   	
										
															//邻接矩阵版dfs
const int maxv = 1000;
const int inf = 1000000000;//
int n, g[maxv][maxv];
bool vis[maxv] = {false};
void dfs(int u, int depth){
	vis[u] = true;//设置u已被访问
	//如果需要对u进行操作,在此进行
	//下面对所有从u出发能到达的分支顶点进行枚举
	for(int v = 0; v < n; v++){
		if(vis[v] == false&& g[u][v] != inf){//如果v未被访问,且u可到达v 
			dfs(v, depth + 1);//访问v,深度+1 
		}
	} 
}
void dfstrave(){
	for(int u = 0; u < n; u++){
		if(vis[u] == false){
			dfs(u, 1);//访问u和u所在的连通块,1表示第一层 
		}
	}
}														



                                                                //邻接表版dfs 
vector<int> adj[maxv];//图g的邻接表 
int n;//顶点数n,maxv为最大顶点数 
bool vis[maxv] = {false};//如果顶点i已被访问,则vis[i] == true,初值为false;
void dfs(int u, int depth){
	vis[u] = true;
	//如果需要对u进行操作,在此进行
	for(int i = 0; i < adj[u].size(); i++){
		int v = adj[u][i];
		if(vis[v] == false){
			dfs(v, depth + 1);
		}
	} 
} 
void dfstrave(){//遍历图g 
	for(int u = 0; u < n; u++){
		if(vis[u] == false) dfs(u, 1);
	}
}		


                                                                //bfs(样板) 
bfs(u){//遍历u的连通块 
	queue q;
	inq[u] = true;
	while(q!empty()){
		取出q的队首元素,进行访问;
		for(从u出发可达的所有顶点v){
			if(inq[v] == false){
				q.push(v);
				inq[v] = true;
			}
		}
	}
}							
bfstrave(g){
	for(g所有顶点u){//枚举g的所有顶点u 
		if(inq[u] == false){
			bfs(u);
		} 
	}
}								 


                                                                //邻接矩阵版bfs
int n, g[maxv][maxv];
bool inq[maxv] = {false};
void bfs(int u){//遍历u所在连通图 
	queue<int> q;
	q.push(u);
	inq[u] = true;
	while(!=empty()){
		int u = q.front();
		q.pop();
		for(int v = 0; v < n; v++){
			if(inq[v] == false&&g[u][v] != inf){
				q.push(v);
				inq[v] = true;
			}
		}
	}
} 
void bfstrave(){
	for(int u = 0; u < n; u++){
		if(inq[u] == false){
			bfs(u);
		}
	}
}
								
								                                    //邻接表版bfs
vector<int> adj[maxv];
int n;
bool inq[maxv] = {false};
void bfs(int u){
	queue<int> q;
	q.push(u);
	inq[u] = true;
	while(!=q.empty()){
		int u = q.front();
		q.pop;
		for(int i = 0; i < adj[u].size(); i++){//对应u出发能到达的所有顶点 
			int v = adj[u][i];
			if(inq[v] == false){
				q.push(v);
				inq[v] = true;     
			}
		}
	}
}																		
void bfstrave(){
	for(int u = 0; u < n; u++){
		if(inq[u] == false){
			bfs(u);
		}
	}
}				

                                                                        //bfs邻接表考虑层数
struct node{
	int v;//顶点编号 
	int layer;//顶点层号 
};						
vector<node> adj[n];
void bfs(int s){
	queue<node> q;
	node start;
	start.v = s;
	start.layer = 0;
	q.push(satrt);
	inq[start.v] = true;
	while(!=empty()){
		node topnode = q.front();
		q.pop();
		int u = topnode.v;
		for(int i = 0; i < adj[u].size(); i++){
			node next = adj[u][i];
			next.layer = topnode.layer + 1;
			if(inq[next.v] == false){
				q.push(next);
				inq[next.v] = true;
			}
		}
	}
}

dijkstra

                                                        //最短路径
//dijkstra算法,(样板)
//g为图,一般设成全局变量;数组d为源点到达各点的最短路径长度,s为起点
dijkstra(g, d[], s){
	初始化,
	for(n次){//1,循环n次,每次从未选中的点中,选出离s最近的点u 
		u = 使d[u]最小的还未被访问的顶点的标号
		记u已被访问;
		for(从u出发能到达的所有顶点v){//2,从u能到达的点中选出从s->u->v的最短距离 
			if(v未被访问&&以u为中介点使s到顶点v的最短距离d[v]更优){
				优化d[v]; 
			}
		} 
	} 
}                                                        
					
					
					                                                    //邻接矩阵版,O(V^2)
const int maxv = 1000;
const int inf = 1000000000;
int n, g[maxv][maxv];//g用来表示边权 
int d[maxv];
bool vis[maxv] = {false};
void dijkstra(int s){
	fill(d, d + maxv, inf){
		d[s] = 0;
		for(int i = 0; i < n; i++){//循环n次 
			int u  = -1, min =  inf;
			for(int j = 0; j < n; j++){//1,
				if(vis[j] == false&& d[j] < min){
					u = j;
					min = d[j];//选出最小d[u] 
				}
			}
			if(u == -1) return;
			vis[u] = true;
			for(int v = 0; v < n; v++){//2
				if(vis[v] == false&&g[u][v] != inf && d[u] + g[u][v] < d[v]){
					d[v] = d[u] + g[u][v];//优化 
				}
			}	
		}
	}
}											


                                                                        //邻接表版
struct node{
	int v, dis;//v表示点,dis表示边权 
};			
vector<node> adj[maxv];
int n;
int d[maxv];
bool vis[maxv] = {false};
void dijkstra(int s){
	fill(d, d + maxv, inf);
	d[s] = 0;
	for(int i = 0; i < n; i++){//遍历n次 
		int u = -1, min = inf;
		for(int j = 0; j < n; j++){//1
			if(vis[j] == false&&d[j] < min){
				u = j;
				min = d[j];
			}
		}
		if(u == -1) return;
		vis[u] = true;
		for(int j  = 0; j < adj[u].size(); j++){//2
			int v = adj[u][j].v;
			if(vis[v] == false&&d[u] + adj[u][j].dis < d[v]){
				d[v] = d[u] + adj[u][j].dis;//优化 
			}
		}
	}
}

dijkstra和简单第二标尺

                                                //输出dijkstra的最短路径
//dijkstra + dfs


                                                            //邻接矩阵(只有一条路径时)
int n, g[maxv][maxv];
int d[maxv];
int pre[maxv];//新加 
bool vis[maxv] = {false};
void dijkstra(int s){
	fill(d, d + maxv, inf);
	for(int i  = 0; i < n; i++) pre[i] = i;//新加,初始化每个前驱为自己
	d[s] = 0;
	for(int i = 0; i < n; i++){
		int u = -1, min = inf;
		for(int j = 0; j < n; j++){
			if(vis[j] == false&&d[j] < min){
				u = j;
				min = d[j];
			}
		}
		if(u =  -1) return;
		vis[u] = true;
		for(int v = 0; v < n; v++){
			if(vis[v] == false&&d[u] + g[u][v] < d[v]){
				d[v] = d[u] + g[u][v];
				pre[v] = u;//新加,v的前驱记为u 
			}
		}
	} 
}											
void dfs(int s, int v){//s为起点,v为当前访问的顶点编号 
	if(v == s){//边界 
		printf("%d\n", s);
		return;
	}
	dfs(s, pre[v]);//递归 
	printf("%d\n", v);//从最深处回来,输出每层的顶点号 
}													

 
                                                                                //新增边权
for(int v = 0; v < n; v++){//2.
	if(vis[v] == false&&g[u][v] != inf){
		if(d[u] + g[u][v] < d[v]){
			d[v] = d[u] + g[u][v];
			c[v] = c[u] + cost[u][v];
		}else if(d[u] + g[u][v] == d[v]&&c[u] + cost[u][v] < c[v]){
			c[v] = c[u] + cost[u][v];
		}
	}
}									


                                                                                //新增点权
for(int v = 0; v < n; v++){
	if(vis[v] == false&&g[u][v] != inf){
		if(d[u] + g[u][v] < d[v]){
			d[v] = d[u] + g[u][v];
			w[v] = w[u] + weight[v];
		}else if(d[u] + g[u][v] == d[v]&&w[u] + weight[v] > w[v]){
			w[v] = w[u] + weight[v];
		}
	}
}									


                                                                                //求最短路径条数
//需要新增一个num[],
for(int v = 0; v < n; v++){
	if(vis[v] == false&& g[u][v] != inf){
		if(d[u] + g[u][v] < d[v]){
			d[v] = d[u] + g[u][v];
			num[v] = num[u];
		}else if(d[u] + g[u][v] == d[v]){
			num[v] += num[u];//累加num 
		}
	}
}

dijkstra和dfs(较复杂的第二第三标尺)

                                                                    //dijkstra + dfs
//用来解决较复杂的第二标尺
//1,先在dijkstra中记录下所有最短路径(只考虑路径),
//2,再从最短路径中选出第一条第二标尺最优路径


int num[maxv];  //用来记录最短路径条数(路径最短) 
vector<int> pre[maxv];
void dijkstra(int s){
	fill(d, d + maxv, inf);
	d[s] = 0;
	for(int i = 0; i < n; i++){
		int u = -1, min = inf;
		for(int j = 0; j < n; j++){
			if(vis[j] == false&&d[j] < min){
				u =  j;
				min = d[j];
			}
		}
		if(u == -1) return;
		for(int v = 0; v < n; v++){
			if(vis[v] == false&&g[u][v] != inf){
				if(d[u] + g[u][v] < d[v]){
					d[v] = d[u] + g[u][v];
					num[v] = num[u];
					pre[v].clear();//清空pre[v]之前的路径 
					pre[v].push_back(u);//令v的前驱为u(因为u的前驱路径更优) 
				}else if(d[u] + g[u][v] == d[v]){
					pre[v].push_back(u);//令v的前驱为u
					num[v] += num[u]; 
				}
			}
		}
	}
}                                                                   
int optvalue;
vector<int> pre[maxv];
vector<int> path, temppath;
void dfs(int v){//v为当前访问结点 
	if(v == st){
		//递归边界,得到一条完整的temppath(优化) 
		temppath.push_back(v);
		int value;
		计算路径temppath上的value值;
		if(value优于optvalue){
			optvalue = value;
			path = temppath;
		} 
		temppath.pop_back();
		return;
	}
	temppath.push_back(v);//递归前,先入矢量 
	for(int i = 0; i < pre[v].size(); i++){//遍历从v开始的所有短路径,(优化第二标尺) 
		dfs(pre[v][i]);
	}
	temppath.pop_back();//
} 
//存放在temppath和path中的路径结点是逆序的,因此访问结点需要倒着进行
                                                                                //计算temppath的边权之和
int value = 0;
for(int i = temppath.size() - 1; i > 0; i--){
	//当前结点id,下一个结点innext
	int id = temppath[i], idnext = temppath[i - 1];
	value += v[id][idnext];//value增加边id->idnext的边权 
}
                                                                                   
																				//点权之和
int value = 0;
for(int i = temppath.size() - 1; i >= 0; i--){//倒着访问 
	int id = temppath[i];
	value += w[id];//value增加结点id的点权 
}

dijkstra实战

                                                                                //对于a1030     travel plan
                                                    //dijkstra算法
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxv = 510;
const int inf = 1000000000;
int n, m, st, ed, g[maxv][maxv], cost[maxv][maxv];
int d[maxv], c[maxv], pre[maxv];
bool vis[maxv] = {false};
void dijkstra(int s){
	fill(d, d + maxv, inf);
	fill(c, c + maxv, inf);
	for(int i = 0; i < n; i++){
		int u = -1, min = inf;
		for(int j = 0; j < n; j++){
			if(vis[j] == false&&d[j] < min){
				u = j;
				min = d[j];
			}
		}
		if(u == -1) return;
		vis[u] = true;
		for(int v = 0; v < n; v++){
			if(vis[v] == false&&g[u][v] != inf){
				if(d[u] + g[u][v] < d[v]){
					d[v] = g[u][v] + d[u];
					c[v] = cost[u][v] + c[u];
					pre[v] = u;
				}else if(d[u] + g[u][v] == d[v]&&c[u] + cost[u][v] < c[v]){
					c[v] = cost[u][v] + c[u];
					pre[v] = u;
				}
			}
		}
	}
}							
void dfs(int v){//从v往回找st 
	if(v == st){
		printf("%d", v);
		return;
	}
	dfs(pre[v]);
	printf("%d ", v);
}					
int main(){
	scanf("%d%d%d%d", &n, &m, &st, &ed);
	int u, v;
	fill(g[0], g[0] + maxv * maxv, inf);
	for(int i = 0; i < m; i++){
		scanf("%d%d", &u, &v);
		scanf("%d%d", &g[u][v], &cost[u][v]);
		g[v][u] = g[u][v];//无向图
		cost[v][u] = cost[u][v]; 
	}
	dijkstra(st);
	dfs(ed);//打印路径 
	printf("%d %d\n", d[ed], c[ed]);
	return 0;
}	 



                                                                                    //dijkstra + dfs
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxv = 510;
const int inf = 1000000000;
int n, m, st, ed, g[maxv][maxv], cost[maxv][maxv];
int d[maxv], mincost = inf;
bool vis[maxv] = {false};
vector<int> pre[maxv];
vector<int> temppath, path;
void dijkstra(int s){//s为起点 
	fill(d, d + maxv, inf);
	d[s] = 0;
	for(int i = 0; i < n; i++){
		int u = -1, min = inf;
		for(int j = 0; j < n; j++){
			if(vis[j] == false&&d[j] < min){
				u = j;
				min = d[j];
			}
		}
		if(u == -1) return;
		vis[u] = true;
		for(int v = 0; v < n; v++){
			if(vis[v] == false&&g[u][v] != inf){
				if(d[u] + g[u][v] < d[v]){
					d[v] = d[u] + g[u][v];
					pre[v].clear();
					pre[v].push_back(u);
				}else if(d[u] + g[u][v] == d[v]){
					pre[v].push_back(u);
				}
			}
		}
	}
}										
void dfs(int v){
	if(v == st){
		temppath.push_back(v);
		int tempcost = 0;
		for(int i = temppath.size() - 1;i > 0; i--){
			int id = temppath[i], idnext = temppath[i-1];
			tempcost += cost[id][idnext];
		}
		if(tempcost < mincost){//优化第二或第三标尺 
			mincost = temppath;
			path = temppath;
		}
		temppath.pop_back();
		return;
	}
	temppath.push_back(v);
	for(int i = 0; i < pre[v].size(); i++){
		dfs(pre[v][i]);
	}
	temppath.pop_back();
}							 
int main(){
	scanf("%d%d%d%d", &n, &m, &st, &ed);
	int u, v;
	fill(g[0], g[0] + maxv * maxv, inf);
	fill(cost[0], cost[0] + maxv * maxv, inf);
	for(int i = 0; i < m; i++){
		scanf("%d%d", &u, &v);
		scanf("%d%d", &g[u][v], &cost[u][v]);
		g[v][u] = g[u][v];
		cost[v][u] = g[u][v];
	}
	dijkstra(st);
	dfs(ed);
	for(int i = path.size() - 1; i >= 0; i--){
		printf("%d ", path[i]);
	}
	printf("%d %d\n", d[ed], mincost);
	return 0;
}

处理负权点spfa

                                                                                        //SPFA算法,(解决有负权图的问题)  
                                                //模板SPFA(最短路径更快算法)
 //期望时间复杂度为O(kE) 
queue<int> q;
源点s入队
while(队列非空){
	取出队首元素u;
	for(u的所有邻接边u->v){
		if(d[u] + dis < d[v]){
			d[v] = d[u] + dis;
			if(v当前不在队列){
				v入队;
				if(v入队次数大于n-1){
					说明有可达负环,retur; 
				} 
			} 
		} 
	} 
}					




                                        //bfs的SPFA                            //邻接表表示
struct node{
	int v, dis;
};
vector<node> adj[maxv];
int n, d[maxv], num[maxv];
bool inq[maxv];
bool spfa(int s){
	memset(inq, false, sizeof(inq));
	memset(num, 0, sizeof(num));
	fill(d, d + maxv, inf);//若是邻接矩阵则用d + maxv * maxv
	//源点入队
	queue<int> q;
	q.push(s);
	inq[s] = true;
	num[s]++;
	d[s] = 0;
	//主体 
	while(!=q.empty()){
		int u = q.front();
		q.pop();
		inq[u] = false;
		//遍历u所有邻接边v
		for(int j = 0; j < adj[u].size(); j++){
			int v = adj[u][j].v;
			int dis = adj[u][j].dis;
			if(d[u] + dis < d[v]){//若可松弛 
				d[v] = d[u] + dis;
				if(!inq[v]){//若v不在队列,(入队,边加一) 
				    q.push(v);
				    inq[v] = true;
				    num[v]++;
				    if(num[v] >= n) return false;
			    }
			} 	
		} 
	} 
	return true;//无可达负环 
}													

//FIFO队列可替换成priority_queue, 加快速度
//或替换成双端队列deque,   加速	

最小生成树kruskal(并查集的应用)

                                                        //最小生成树,
//kruskal算法(并查集的应用),采用边贪心策略
											

                                                                //kruskal算法模板
int kruskal(){
	令最小生成树的边权之和为ans, 最小生成树的当前边数num_edge;
	将所有边按边权从小到大排序;
	for(从小到大枚举所有边){
		if(当前测试的两个端点在不同的连通块中){
			将该测试边加入最小生成树中;
			ans += 测试边的边权;
			最小生成树的当前边数num_edge加1;
			当边数num_edge等于顶点数减1时结束循环; 
		} 
	} 
	return ans; 
}


			
struct edge{
	int u, v;//边的两端点
	int cost; 
}e[maxe];
bool cmp(edge a, edge b){//让边权从小到大排序 
	return a.cost < b.cost; 
}

                                                                    //kruskal算法O(eloge),用于边少 
int father[n];
int findfather(int x){
	if(x == father[x] return x;//边界 
	else{
		t = findfather(father[x]);//递归式 
		father[x] = t;
		return t;
	}
}										
int kruskal(int n, int m){
	int ans = 0, num_edge = 0;//ans为边权之和,num_edge为当前生成树边数 
	for(int i = 0; i <= n; i++){
		father[i] = i;//并查集初始化 
	}
	sort(e, e + m, cmp);//对边从小到大排序 
	for(int i = 0; i < m; i++){//对于边i的两个顶点u,v 
		int fau = findfather(e[i].u);
		int fav = findfather(e[i].v); 
		if(fau != fav){
			father[fau] = fav;//把测试边加入最小生成树 
			ans += e[i].cost;
			num_edge++;
			if(num_edge == n-1) break;//边数为n-1就遍历完整个连通图 
		}
	}
	if(num_edge != n-1) return -1;//不是连通图,返回-1 
	else return ans;
}

kruskal实战

                                                    //kruskal实战
#include<iostream>
#include<algorithm>
using namespace std;
const int maxv = 110;
const int maxe = 10010;
//边集定义部分
struct edge{
	int u, v;
	int cost;
}e[maxe];
bool cmp(edge a, edge b){
	return a.cost < b.cost;
}						
//并查集部分
int father[maxv];
int findfather(int x){
	if(x == father[x]) return x;
	else{
		int t = findfather(father[x]);
		father[x] = t;
		return t;
	}
}				
//kruskal部分
int kruskal(int n, int m){
	int ans = 0, num_edge = 0;
	for(int i = 0; i < n; i++){
		father[i] = i;
	}
	sort(e, e + m, cmp);
	for(int i = 0; i < m; i++){
		int fau = findfather(e[i].u);
		int fav = findfather(e[i].v);
		if(fav != fau){
			father[fav] = fau;
			ans += e[i].cost;
			num_edge++;
			if(num_edge == n - 1) break;
		}
	}
	if(num_edge != n - 1) return -1;
	else return ans;
}			 
int main(){
	int n, m;
	scanf("%d%d", &n, &m);
	for(int i = 0; i < m; i++){
		scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].cost);
	}
	int ans = kruskal(n, m);
	printf("%d\n", ans);
	return 0;
}

forwards on weibo

                        //forwards on weibo
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxv = 1010;
struct node{
	int id;
	int layer;
};
vector<node> adj[maxv];
bool inq[maxv] = {false};
int bfs(int s, int l){
	int numforward = 0;
	queue<node> q;
	node start;
	start.id = s;
	start.layer = 0;
	q.push(start);
	inq[start.id] = true;
	while(!q.empty()){
		node topnode =  q.front();
		q.pop();
		int u = topnode.id;
		for(int i = 0; i < adj[u].size(); i++){
			node next = adj[u][i];
			next.layer = topnode.layer + 1;
			if(inq[next.id] == false&& next.layer <= l){
				q.push(next);
				inq[next.id] = true;
				numforward++;
			}
		}
	}
	return numforward;
}
int main(){
	node user;
	int n, l, numfollow, idfollow;
	scanf("%d%d", &n, &l);
	for(int i = 1; i <= n; i++){
		user.id = i;
		scanf("%d", &numfollow);
		for(int j = 0; j < numfollow; j++){
			scanf("%d", &idfollow);
			adj[idfollow].push_back(user);
		}
	}
	int numquery, s;
	scanf("%d", &numquery);
	for(int i = 0; i < numquery; i++){
		memset(inq, false, sizeof(inq));
		scanf("%d", &s);
		int numforward = bfs(s, l);
		printf("%d\n", numforward);
	}
	return 0;
}

拓扑排序

                                                                    //拓朴排序
//topo用来判断图是否为有向无环                                                                    
//拓扑排序:在有向图中,对所有结点排序,要求没有一个结点指向它前面的结点

//对于priority_queue 可以保持队首是最小元素(set也可) 


                                                                    //邻接表版
vector<int> g[maxv];//g[v]表示v的出边 
int n, m, in[maxv];//顶点数,入度
bool toposort(){
	int num = 0;
	queue<int> q;
	for(int i = 0; i < n; i++){//将所有入度为0的顶点入队 
		if(in[i] == 0){
			q.push(i);
		}
	}
	while(!q.empty()){
		int u = q.front();
		//printf("%d", u);         //可输出顶点u,作为拓扑排序的顶点
		q.pop();
		for(int i = 0; i < g[u].size(); i++){//对于u的所有出点v 
			int v = g[u][i];
			in--;
			if(in[v] == 0){
				q.push(v);
			}
		} 
		g[u].clear();//清空u的出边,表示u的出点访问完(无必要可不写) 
		num++;
	}
	if(num == n) return true;//topo成功 
	else return false;
}

floyd(全源最短路径)

                                                                //floyd算法
//解决全源最短路径,(求任意两点u,v之间的最短路径长度,时间复杂度为O(n^3)),n在200以内 


                                                    //模板
枚举顶点k∈[1,n]
    以顶点k为中介点,枚举所有顶点对i和j(i∈[1, n], j∈[1, n])
	    如果dis[i][k] + dis[k][j] < dis[i][j]成立;
		    赋值dis[i][j] = dis[i][k] + dis[k][j];
			
			
			                                                                //floyd算法代码
#include<cstdio>
#include<algorithm>
using namespace std;
const int inf = 1000000000;
const int maxv = 200;
int n, m;
int dis[maxv][maxv];
void floyd(){
	for(int k = 0; k < n; k++){//以k为中介点,则k在最前面枚举, 
		for(int i = 0; i < n; i++){
			for(int j = 0; j < n; j++){
				if(dis[i][k] !=  inf&&dis[k][j] != inf&&dis[i][k] + dis[k][j] < dis[i][j]){
					dis[i][j] = dis[i][k] + dis[k][j];//找到更短路径  
				}
			}
		}
	}
}															
int main(){
	int u, v, w;
	fill(dis[0], dis[0] + maxv * maxv, inf);
	scanf("%d%d", &n, &m);
	for(int i = 0; i < n; i++){
		dis[i][i] = 0;//顶点i到i距离为0 
	}
	for(int i = 0; i < m; i++){
		scanf("%d%d%d", &u, &v, &w);
		dis[u][v] = w;
	}
	floyd();//
	for(int i = 0; i < n; i++){//输出最短路径,分别以0~n-1为起点到0~n-1的最短距离(全源最短路径) 
		for(int j = 0; j < n; j++){
			printf("%d ", dis[i][j]);
		}
		printf("\n");
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值