Week 9 图论

文章展示了C++实现的图算法,包括基于深度优先遍历(DFS)和广度优先遍历(BFS)的图搜索,以及Floyd算法和Dijkstra算法求解单源最短路径问题。示例代码涵盖了邻接矩阵和链式前向星两种数据结构的使用。
摘要由CSDN通过智能技术生成

P5318 【深基18.例3】查找文献 

 

#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
struct edge{       //存边结构体
	int u,v;
}; 
vector <int> e[100001];  //两个vector
vector <edge> s;
bool vis1[100001]={0},vis2[100001]={0}; //标记数组
bool cmp(edge x,edge y){  //cmp排序规则
	if(x.v==y.v)
	return x.u<y.u;
	else return x.v<y.v;
}
void dfs(int x){  //深度优先遍历
	vis1[x]=1;
	cout<<x<<" ";
	for(int i=0;i<e[x].size();i++){
		int point=s[e[x][i]].v;
		if(!vis1[point]){
			dfs(point);
		}
	}
}
void bfs(int x){  //广度优先遍历
	queue <int> q;
	q.push(x);
	cout<<x<<" ";
	vis2[x]=1;
	while(!q.empty()){
		int fro=q.front();
		for(int i=0;i<e[fro].size();i++){
			int point=s[e[fro][i]].v;
			if(!vis2[point]){
				q.push(point); 
				cout<<point<<" ";
				vis2[point]=1;
			}
		}
		q.pop();
	}
}
int main(){
	int n,m;  //输入,存边
	cin>>n>>m; 
	for(int i=0;i<m;i++){
		int uu,vv;
		cin>>uu>>vv;
		s.push_back((edge){uu,vv});   
	}
	sort(s.begin(),s.end(),cmp);  //排序
	for(int i=0;i<m;i++)   
		e[s[i].u].push_back(i); 
	dfs(1);   //从1号顶点开始深搜
	cout<<endl;
	bfs(1);   //广搜
}

 U80592 【模板】floyd

#include<iostream>
#include<cstring>
using namespace std;
#define MAXN 501
#define MAXM 10001
#define MOD 998244354
int e[MAXN][MAXN];
int main()
{
    int n, m;
    cin >> n >> m;
    //使用邻接矩阵存储
    memset(e, 0x3f, sizeof(e));
    for (int i = 0; i < m; i++)
    {
        int from, to, l;
        cin >> from >> to >> l;
        e[from][to] = min(l, e[from][to]);
        //无向图
        e[to][from] = min(l, e[to][from]);
    }
    for (int i = 1; i <=n; i++)
    {
        e[i][i] = 0;
    }
    //Floyd模板
    for (int k = 1; k <= n; k++)
    {
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                e[i][j] = min(e[i][k] + e[k][j], e[i][j]);
            }
        }
    }
    //计算和并输出
    for (int i = 1; i <= n; i++)
    {
        int dis = 0;
        for (int j = 1; j <= n; j++)
        {
            dis += e[i][j];
            dis %= MOD;
        }
        cout << dis << endl;
    }
    return 0;
}

 P4779 【模板】单源最短路径(标准版)


#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
#define MAXN 100001
#define MAXM 200002

//使用链式前向星
//边的结构体
struct edge
{
    //下一条边、这条边的另一个端点、距离
    int next, to, d;
    //用于优先队列排序
    bool operator<(const edge& another) const
    {
        return d > another.d;
    }
};
//所有边
edge e[MAXM];
//链式前向星头、边计数(用于添加)
int head[MAXN], edgeCount = 0;
//Dijkstra的是否在集合中
bool vis[MAXN];
//存储距离
int dis[MAXN];

//添加边
//参数:起点、终点、距离
void add(int from, int to, int d)
{
    e[++edgeCount].to = to;
    e[edgeCount].next = head[from];
    e[edgeCount].d = d;
    head[from] = edgeCount;
}
//优先队列(Dijkstra的优化)
priority_queue<edge> q;

int main()
{
    int n, m, s;
    cin >> n >> m >> s;
    for (int i = 1; i <= m; i++)
    {
        int from, to, d;
        cin >> from >> to >> d;
        add(from, to, d);
    }
    //初始化所有距离无穷远
    memset(dis, 0x3f, sizeof(dis));
    //起点距离为0
    dis[s] = 0;
    //把起点放入优先队列
    q.push({0, s, 0});
    //Dijkstra
    while (!q.empty())
    {
        //点
        int k = q.top().to;
        q.pop();
        //在集合中就不再处理
        if (vis[k])
        {
            continue;
        }
        //标记再集合中
        vis[k] = true;
        //遍历所有相连的点
        for (int i = head[k]; i != 0; i = e[i].next)
        {
            //更新距离
            int to = e[i].to;
            dis[to] = min(dis[k] + e[i].d, dis[to]);
            //放入队列
            if (!vis[to])
            {
                q.push({0, to, dis[to]});
            }
        }
    }
    
    for (int i = 1; i <= n; i++)
    {
        cout << dis[i] << ' ';
    }

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值