1.建立一个结构体以存放邻接表:struct edge(int to,dist; edge*next)
2.每一次读入一组数据,每个节点都有一个链表,里面保存着从该节点出发的所有边:
void add( int u , int v , int d ) {
pt -> to = v;
pt -> dist = d;
pt -> next = head[ u ]; //head存放第一条边,且同一个起点的各条边在邻接表中的书序和读入顺序正好相反;
head[ u ] = pt++; //这里pt++是申请内存吧;
} //同时注意无向图每条边会在邻接表中出现两次;
3.重磅戏,优先队列然后加个什么什么函数(记住就好了吧==):
struct node {
int x , d; //x是编号,d是距离起点的距离,加一个d[]数组很明显避免了对链表的遍历;
bool operator < ( const node &rhs ) const {
return d > rhs.d;
}
};
int d[ maxn ];
priority_queue< node > Q;
4.然后很简单啦,明白dijkstra原理就不难写出来了:
void dijkstra( int S ) {
clr( d , inf );
d[ S ] = 0;
Q.push( ( node ) { S , 0 } );
while( ! Q.empty() ) {
node o = Q.top();
Q.pop();
int x = o.x , dist = o.d;
if( dist != d[ x ] ) continue;
for( edge* e = head[ x ] ; e ; e = e -> next ) { //当全部的节点都遍历完毕后,e==0了;
int to = e -> to;
if( d[ to ] > dist + e -> dist ) {
d[ to ] = dist + e -> dist;
Q.push( ( node ) { to , d[ to ] } );
}
}
}
}
ps:最重要的地方在优先队列(。。。),因为要排的是距离起点的大小,很明显,如果用存储的像spfa一样只是存储节点是不行的,所以要两个一起上!
完了。。。大概只有我这种低智商的才需要慢慢分析吧==加油