关于最短路径的基础操作

作为 在图论中的基础就是打邻接表,用来存储点与点之间的关系,常用的操作就是直接开二维数组,然后双重for循环,判断关系,直接打出来,但是这样的操作并不适合所有情况,当点剧集密度比较大(稠密图)

,数据范围不太大,时间要求不高的时候适合,因为可能会RE或者LT.。所以慢慢就有了两种更加合适的邻接表表示方式,vector 和 静态链表。

我一开始超喜欢开二维数组表示邻接矩阵,但是在某些题目中,会让你修改到怀疑人生,所以,一上来就用后两种,会减少后期因为时间 数据范围等不合适造成的错误。

vector表示邻接表:(vector 可以自己开不定长度的数组,利用这个特性,来达到空间最优)

struct node{
	int id;
	int d;
};
vector<node> q[maxn];
void init(int n)//初始化q数组 
{
	for(int i=0;i<=n;i++)
		q[i].clear(); 
}
void add(int x,int y,int d)
{//将t压入q数组 
	node t;
	t.id=y;
	t.d=d;
	q[x].push_back(t);//压入数组尾部 
}
for(int i=0;i<q.size();i++)
{
	int v=q[i].id;
	int d=q[i].d;	
} 

 虽然知道这个vector,但是,,作为小白的我,很少用过它,更喜欢用静态链表,因为用起来舒坦

struct node{
	int id;
	int d;
	int next;
}side[maxn];

void init()
{
	memset(head,-1,sizeof(head));
	cnt=0;
}

void add(int x,int y,int d)
{
	side[cnt].id=y;
	side[cnt].d=d;
	side[cnt].next=head[x];
	head[x]=cnt++;
}

for(int j=head[i];j!=-1;j=side[j].next)
{
	int v=side[j].d;
	int u=side[j].id;
}//实质是头插 

有了邻接表之后,就可以自然的进阶实现拓扑排序,还是以静态链表实现

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#define maxn 10000
using namespace std;

int n,m,cnt;
int head[maxn];
int in[maxn];
int ans[maxn];
struct node{
	int id;
	int d;
	int next;
}side[maxn];


void init()
{
	memset(head,-1,sizeof(head));
	cnt=0;
}

void add(int x,int y,int d)
{
	side[cnt].id=y;
	side[cnt].d=d;
	side[cnt].next=head[x];
	head[x]=cnt++;
}

int main()
{
	while(scanf("%d%d",&n,&m)!=EOF)
	{
	//	memset(mark,0,sizeof(mark)); 
		init();
		for(int i=0;i<m;i++)
		{
			int a,b;
			scanf("%d%d",&a,&b);
			add(a,b,0);
			//in[a]++;
			in[b]++;
		}
		priority_queue<int,vector<int>,greater<int>  > pq;
		for(int i=1;i<=n;i++)
			if(in[i]==0)
				pq.push(i);
		int k=0;
		while(pq.size())
		{
			int x=pq.top();
			ans[k++]=x;
			pq.pop();
			for(int j=head[x];j!=-1;j=side[j].next)
			{
				int y=side[j].id;
				in[y]--;
				if(in[y]==0) pq.push(y);
			}
		}
		for(int i=0;i<k;i++)
			printf("%d ",ans[i]);
		
	}
	return 0;
}

并不是什么ac代码,只是敲的实例而已,拓扑排序,重要的是要掌握对优先队列的处理.

priority_queue默认为大顶堆,即堆顶元素为堆中最大元素。如果我们想要用小顶堆的话需要增加使用两个参数:priority_queue<int, vector<int>, greater<int> > q; // 小顶堆//升序

priority_queue<int, vector<int>, less<int> > q; // 大顶堆//降序

猜你喜欢

转载自blog.csdn.net/qq_42505741/article/details/81355394