洛谷 acwing刷题 有关图的存储形式和djstra算法的例题
在以往的408学习中,我们 往往采用邻接表和邻接矩阵解决图的存储问题,
但是经过刷题过程发现也有一种新的存储形式值得我们学习,废话不多说,直接上代码
讲解
初始的数组
int e[N], w[N], ne[N], h[H], idx;
算法过程
void add(int x, int y, int z) {
//e[i]表示 第i条边指向的目标节点
e[idx] = y;
// w[i]表示 第i条边的权重
w[idx] = z;
//ne表示边的索引 ne[i] = ?表示 第i条边的下一条边是哪条边
ne[idx] = h[x];
//h[H]:每个节点的第一条边,h[1] = 3从点1 出发的第一条边是 3号边。
h[x] = idx++;
}
看点例题
Welcome - Luogu Spilopelia
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
const int N=2e5+10;
int h[N],e[N],ne[N],w[N],idx;
int d[N];
bool vis[N];
bool t[103][103];//t[i][j]=true代表从i到j的道路损坏
typedef pair<int,int> PII;
struct node{
int u,v,w;
}p[N];
void add(int x,int y,int z)
{
e[idx]=y;
w[idx]=z;
ne[idx]=h[x];
h[x]=idx++;
}
void dijkstra(int x)
{
memset(d,0x3f,sizeof d);
d[x]=0;
priority_queue<PII,vector<PII>,greater<PII> >q;
q.push({d[x],x});
while(!q.empty())
{
int now=q.top().second;
q.pop();
if(vis[now]) continue;
vis[now]=true;
for(int i=h[now];i!=-1;i=ne[i])
{
int j=e[i];
if(d[j]>d[now]+w[i])
{
d[j]=d[now]+w[i];
q.push({d[j],j});
}
}
}
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
h[i]=-1;
for(int i=1;i<=m;i++)
scanf("%d%d%d",&p[i].u,&p[i].v,&p[i].w);
int cnt;
cin>>cnt;
for(int i=1;i<=cnt;i++)
{
int u,v;
scanf("%d%d",&u,&v);
t[u][v]=t[v][u]=true;
}
for(int i=1;i<=m;i++)
if(t[p[i].u][p[i].v])
{
add(p[i].u,p[i].v,p[i].w);
add(p[i].v,p[i].u,p[i].w);
}
else
{
add(p[i].u,p[i].v,0);
add(p[i].v,p[i].u,0);
}
int b,e;
cin>>b>>e;
dijkstra(b);
printf("%d\n",d[e]);
return 0;
}
看点例题
https://www.acwing.com/solution/content/49931/
这个代码我写错了,但是思路感觉没啥问题
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
using LL = long long;
const int N = 110, M = 510, P = 100000;
int n, m;
int h[N], e[2*M], w[2*M], ne[2*M], idx;
int dist[N], p[N];
bool vis[N];
int qmi(int a, int b, int p){
int res = 1;
while(b){
if(b & 1) res = (LL)res * a % p;
b >>= 1;
a = (LL)a * a % p;
}
return res % p;
}
int find(int x){
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
void add(int a, int b, int c){
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
void dijkstra(){
memset(dist, 0x3f, sizeof(dist));
dist[0] = 0;
for(int i = 1; i <= n; ++i){
int t = -1;
for(int j = 0; j < n; ++j){
if(!vis[j] && (t == -1 || dist[t] > dist[j])){
t = j;
}
}
vis[t] = true;
for(int i = h[t]; i != -1; i = ne[i]){
int j = e[i];
if(dist[j] > dist[t] + w[i]){
dist[j] = dist[t] + w[i];
}
}
}
}
int main()
{
cin >> n >> m;
memset(h, -1, sizeof(h));
for(int i = 0; i < n; ++i) p[i] = i;
for(int i = 0; i < m; ++i){
int a, b, c;
cin >> a >> b;
int aa = find(a), bb = find(b);
if(aa != bb){
p[aa] = bb;
c = qmi(2, i, P);
add(a, b, c);
add(b, a, c);
}
else continue;
}
dijkstra();
for(int i = 1; i < n; ++i){
if(dist[i] == 0x3f3f3f3f) cout << "-1" << endl;
else cout << dist[i] % P << endl;
}
return 0;
}
// 作者:Asiim0v
// 链接:https://www.acwing.com/solution/content/49931/
// 来源:AcWing
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。