最短路的算法有Dijkstra,Bellman-Flody,SPFA,Flody
- 较为常用的就是Dijkstra,Flody
Dijkstra 利用邻接表存图
Flody利用邻接矩阵存图
cpp 代码
题目:
https://vjudge.net/problem/POJ-1847
直接暴力Flody ( )
/**
*Flody
*@author Hongchuan CAO
*/
#include<iostream>
#include<algorithm>
#include<cstdlib>
using namespace std;
const int Maxx = 1000000;
int G[110][110];
int n,a,b;
void get_data(){
for(int i=0;i<110;i++)
for(int j=0;j<110;j++){
if(i==j){
G[i][j] = 0;
continue;
}
G[i][j] = Maxx;
}
cin>>n>>a>>b;
for(int i=1;i<=n;i++){
int t; cin>>t;
for(int j=1;j<=t;j++){
int to; cin>>to;
if(j==1) G[i][to] = 0;
else G[i][to] = 1;
}
}
}
void Foldy(){
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
G[i][j] = min(G[i][j],G[i][k]+G[k][j]);
}
}
}
if(G[a][b]>=Maxx)
cout<<"-1"<<endl;
else
cout<<G[a][b]<<endl;
}
int main(){
get_data();
Foldy();
return 0;
}
Dijkstra(没有任何优化 )
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdlib>
using namespace std;
const int Maxx = 10000000;
int n,a,b;
class Node{
public:
int to,val;
Node(int x1,int x2){
to = x1;
val = x2;
}
};
vector<Node> G[110]; //邻接表
void get_data(){
cin>>n>>a>>b;
for(int i=1;i<=n;i++){
int t; cin>>t;
for(int j=1;j<=t;j++){
int ato; cin>>ato;
if(j==1) G[i].push_back(Node(ato,0));
else G[i].push_back(Node(ato,1));
}
}
}
void dijkstra(){
bool use[110];
int dis[110];
for(int i=0;i<110;i++){
use[i] = false;
dis[i] = Maxx;
}
dis[a] = 0;
while(true){
int index = 0;
for(int i=1;i<=n;i++){
if(!use[i]&&(index==0||dis[i]<dis[index])) index=i;
}
if(index==0) break;
use[index] = true;
//relax
// for(Node xx:G[index]){
// dis[xx.to] = min(dis[xx.to],dis[index]+xx.val);
// }
for(int i=0;i<G[index].size();i++){
dis[G[index][i].to] = min(dis[G[index][i].to],dis[index]+G[index][i].val);
}
}
if(dis[b]>=Maxx){
cout<<"-1"<<endl;
}else{
cout<<dis[b]<<endl;
}
}
int main(){
get_data();
dijkstra();
system("pause");
return 0;
}
Dijkstra(利用优先队列进行优化 )
priority_queue默认为大根堆(从大到小),所以对于自己创建的类中必须重载小于运算符(或者写一个cmp类重载括号()运算符)
此处我们想要优先输入小的值,所以将小于运算符重载为大于号
具体细节可参考https://www.cnblogs.com/flyoung2008/articles/2136485.html
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdlib>
#include<queue>
using namespace std;
const int Maxx = 10000000;
int n,a,b;
class Node{
public:
int to,val;
Node(int x1,int x2){
to = x1;
val = x2;
}
};
class cmp{
public:
bool operator()(const Node& node1,const Node& node2){
return node1.val>node2.val;
}
};
vector<Node> G[110]; //邻接表
priority_queue<Node,vector<Node>,cmp> que;
void get_data(){
cin>>n>>a>>b;
for(int i=1;i<=n;i++){
int t; cin>>t;
for(int j=1;j<=t;j++){
int ato; cin>>ato;
if(j==1) G[i].push_back(Node(ato,0));
else G[i].push_back(Node(ato,1));
}
}
}
void dijkstra(){
bool use[110];
int dis[110];
for(int i=0;i<110;i++){
use[i] = false;
dis[i] = Maxx;
}
dis[a] = 0;
que.push(Node(a,0));
while(!que.empty()){
Node cur = que.top();
que.pop();
if(use[cur.to]) continue; //if used next
use[cur.to] = true;
//relax
for(int i=0;i<G[cur.to].size();i++){
if(!use[G[cur.to][i].to]&&dis[G[cur.to][i].to]>dis[cur.to]+G[cur.to][i].val){
dis[G[cur.to][i].to] = dis[cur.to]+G[cur.to][i].val;
que.push(Node(G[cur.to][i].to,dis[G[cur.to][i].to]));
}
}
}
if(dis[b]>=Maxx){
cout<<"-1"<<endl;
}else{
cout<<dis[b]<<endl;
}
}
int main(){
get_data();
dijkstra();
return 0;
}
SPFA
题目:
https://vjudge.net/problem/HDU-2066
/**
*SPFA (store in vector)
*HDU-2066
*@author Hongchuan CAO
*
*/
#include<iostream>
#include<vector>
#include<queue>
#include<cstdlib>
#include<algorithm>
#define Maxx 1010
#define max_size 10000000
using namespace std;
int t,s,d;
class Node{
public:
int to,val;
Node(int to,int val){
this->to = to;
this->val = val;
}
};
vector<Node> path[Maxx];
vector<int> endpoint;
int dis[Maxx];
void add_element(int starts,int ends,int vals){
bool find = false;
for(int i=0;i<path[starts].size();i++){
if(path[starts][i].to==ends&&path[starts][i].val>vals){
path[starts][i].val = vals;
find = true;
break;
}
}
//change the next
if(find){
for(int i=0;i<path[ends].size();i++){
if(path[ends][i].to==starts){
path[ends][i].val = vals;
break;
}
}
}else{
path[starts].push_back(Node(ends,vals));
path[ends].push_back(Node(starts,vals));
}
}
int spfa(){
queue<int> que;
que.push(0); //start from zero
while(!que.empty()){
int cur = que.front();
que.pop();
//此处可以统计松弛次数,如果松弛超过n次,说明有负环
for(int i=0;i<path[cur].size();i++){
if(dis[path[cur][i].to]>dis[cur]+path[cur][i].val){
dis[path[cur][i].to]=dis[cur] + path[cur][i].val;
que.push(path[cur][i].to);
}
}
}
int minn = max_size;
for(int i=0;i<endpoint.size();i++){
minn = min(minn,dis[endpoint[i]]);
}
return minn;
}
void solve(){
while(cin>>t>>s>>d){
//clear
for(int i=0;i<Maxx;i++){
dis[i] = max_size;
path[i].clear();
}
endpoint.clear();
dis[0] = 0;
while(t--){
int start,ends,val;
cin>>start>>ends>>val;
add_element(start,ends,val);
}
while(s--){
int to; cin>>to;
add_element(0,to,0);
}
while(d--){
int to; cin>>to;
endpoint.push_back(to);
}
cout<<spfa()<<endl;
}
}
int main(){
ios::sync_with_stdio(false);
solve();
return 0;
}