图论
存图
图分两种,一种是无向图,一种是有向图
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e3+5;
ll mp1[N][N];
vector<ll> mp2[N];
ll n,m;
int main()
{
cin>>n>>m;
while(m--)
{
ll x,y;
cin>>x>>y;
mp1[x][y] = 1;
mp1[y][x] = 1;
//邻接矩阵存图
mp2[x].push_back(y);
mp2[y].push_back(x);
//邻接表存图
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
cout<<mp1[i][j]<<" ";
cout<<"\n";
}
for(int i=1;i<=n;i++)
{
cout<<mp2[i].size()<<" ";
sort(mp2[i].begin(),mp2[i].end());
for(int j=0;j<mp2[i].size();j++)
cout<<mp2[i][j]<<" ";
cout<<"\n";
}
return 0;
}
Dijkstra最短路径算法
Dijkstra算法算是贪心思想实现的,首先把起点到所有点的距离存下来找个最短的,然后松弛一次再找出最短的,所谓的松弛操作就是,遍历一遍看通过刚刚找到的距离最短的点作为中转站会不会更近,如果更近了就更新距离,这样把所有的点找遍之后就存下了起点到其他所有点的最短距离,下面仔细讲。
参数解释:
Chara数组 :储存两点间的距离,Chara[i][j]的值就是点i到点j的距离。 dis数组:储存起点到各个点的距离,dis[i]就是起点到i点的距离。 vis数组:标记点是否访问过 INF:宏定义的最大值路不通
算法思想
有两个数组,dis和vis含义参见上面,初始时vis中只有起点,更新dis中的起点到所有点的距离. 遍历所有节点,找到距离起点最近的一个点K,将这个点加入vis中标记 进行松弛操作,遍历没有在vis数组中的其他所有点,比较起点——>该点和起点——>K点——>该点的距离, 重复2-3操作,直到所有的点遍历完
#define INF 65535
int n,m,s,t;
int Chara[N][N],dis[N],vis[N],p[i];
void Dijkstra(int src) //src传入的起点
{
for(int i=0; i<m; i++) //初始化起点到所有点的距离
{
dis[i] = Chara[src][i];
vis[i] = 0;
p[i]=0;
}
dis[src] = 0; //到自身距离为0
vis[src] = 1; //标记 注src=0
for(int i=0; i<m; i++)
{
int ans = INF,k;
for(int j=0; j<m; j++) // 寻找未被访问过距离起点v0最近的
{
if(!vis[j] && dis[j] < ans)
{
k = j;
ans = dis[j];
}
}
vis[k] = 1; //标记已访问
if(ans == INF) break; //表示剩下所有点都不通
for(int j =0; j<m; j++) //松弛操作,更新起点到所有未访问点的距离
{
if(!vis[j] && dis[k] + Chara[k][j]<dis[j] )
{
dis[j] = dis[k] + Chara[k][j];
p[j]=k;//存放前驱节点
}
}
}
}