您的位置:首页 > 其它

1018. Public Bike Management (30) @ PAT (Advanced Level) Practise

2013-08-21 14:23 435 查看



对Dijkstra算法的复习

求解从s点到t点的最短路径

#include<iostream>
#include<vector>

using namespace std;

#define INF 0x6FFFFFFF

struct Edge
{
int v,dist;
Edge(int _v,int _dist):v(_v),dist(_dist){}
};
struct Node
{
int dist;
bool visited;
vector<int> pre;
};

vector<Node> city;
vector<vector<Edge>> G;

int n;//vertexs
int m;//edges

void Dijkstra(int s,int t)
{
//init
city.clear();
city.resize(n+1);

for(int i=0;i<=n;i++)
{
city[i].visited=false;
city[i].dist=INF;
}
city[s].dist=0;

while(true)
{
//find min
int index=-1;
int mindist=INF;
for(int i=0;i<=n;i++)
{
if(city[i].dist<mindist && !city[i].visited)
{
index=i;
mindist=city[i].dist;
}
}
if(index==-1)
return ;
city[index].visited=true;

//scan the neighborhood
for(int i=0;i<G[index].size();i++)
{
int v=G[index][i].v;
if(!city[v].visited)
{
if(city[v].dist>(city[index].dist+G[index][i].dist))
{
city[v].pre.clear();
city[v].pre.push_back(index);
city[v].dist=city[index].dist+G[index][i].dist;
}
else if(city[v].dist==(city[index].dist+G[index][i].dist))
{
city[v].pre.push_back(index);
}
}
}
}

return ;
}

int main()
{
cin>>n>>m;
int a,b,c;
G.clear();
G.resize(n+1);
for(int i=0;i<m;i++)
{
cin>>a>>b>>c;
G[a].push_back(Edge(b,c));
G[b].push_back(Edge(a,c));
}
while(true)
{
int s,t;
cin>>s>>t;
if(s==-1 || t==-1)
break;
Dijkstra(s,t);
cout<<"smallest dist:"<<city[t].dist<<endl;
for(int i=0;i<city.size();i++)
{
cout<<"vertex["<<i<<"]:"<<city[i].dist<<"  ";
for(int j=0;j<city[i].pre.size();j++)
{
cout<<city[i].pre[j]<<" ";
}
cout<<endl;
}
}

return 0;
}


2个测试用的图:

6 9
0 1 7
0 2 9
0 5 14
1 2 10
1 3 15
2 3 11
2 5 2
3 4 6
4 5 9

==============

4 5
0 1 1
0 2 1
0 3 3
1 3 1
2 3 1
==============
8 9
0 1 1
0 2 1
1 3 1
1 4 1
2 5 1
2 6 1
3 7 1
4 7 1
5 6 1


复习一下DFS

ps.关于DFS遍历最短路径,在下面一小节中

#include<iostream>
#include<vector>

using namespace std;

#define INF 0x6FFFFFFF

struct Edge
{
int v,dist;
Edge(int _v,int _dist):v(_v),dist(_dist){}
};
struct Node
{
int dist;
bool visited;
vector<int> pre;
};

vector<Node> city;
vector<vector<Edge>> G;

vector<int> DFSPath;
int n;//vertexs
int m;//edges

void Dijkstra(int s,int t)
{
//init
city.clear();
city.resize(n+1);

for(int i=0;i<=n;i++)
{
city[i].visited=false;
city[i].dist=INF;
}
city[s].dist=0;

while(true)
{
//find min
int index=-1;
int mindist=INF;
for(int i=0;i<=n;i++)
{
if(city[i].dist<mindist && !city[i].visited)
{
index=i;
mindist=city[i].dist;
}
}
if(index==-1)
return ;
city[index].visited=true;

//scan the neighborhood
for(int i=0;i<G[index].size();i++)
{
int v=G[index][i].v;
if(!city[v].visited)
{
if(city[v].dist>(city[index].dist+G[index][i].dist))
{
city[v].pre.clear();
city[v].pre.push_back(index);
city[v].dist=city[index].dist+G[index][i].dist;
}
else if(city[v].dist==(city[index].dist+G[index][i].dist))
{
city[v].pre.push_back(index);
}
}
}
}

return ;
}

void DFS(int s,int t)
{
city[s].visited=true;
DFSPath.push_back(s);
for(int i=0;i<G[s].size();i++)
{
int v=G[s][i].v;
if(!city[v].visited)
{
DFS(v,t);
}
}
return;
}
int main()
{
cin>>n>>m;
int a,b,c;
G.clear();
G.resize(n+1);
for(int i=0;i<m;i++)
{
cin>>a>>b>>c;
G[a].push_back(Edge(b,c));
G[b].push_back(Edge(a,c));
}
while(true)
{
int s,t;
cin>>s>>t;
if(s==-1 || t==-1)
break;

//Dijkstra
Dijkstra(s,t);
cout<<"smallest dist:"<<city[t].dist<<endl;
for(int i=0;i<city.size();i++)
{
cout<<"vertex["<<i<<"]:"<<city[i].dist<<"  ";
for(int j=0;j<city[i].pre.size();j++)
{
cout<<city[i].pre[j]<<" ";
}
cout<<endl;
}

//DFS
//init
for(int i=0;i<city.size();i++)
city[i].visited=false;

DFS(s,t);
//display the path
for(int j=0;j<DFSPath.size();j++)
cout<<DFSPath[j]<<" " ;
cout<<endl;
}

return 0;
}


A1018的解

整体思路:首先用Dijkstra算法找到所有最短路径,并在每个节点上记录最短路径时的所有前缀。然后从目标点到源(t->s)按每个结点记录的前缀向量表深度优先遍历(DFS,findBestPath函数)出所有最短的路径。对每条最短路径计算需要带出的车数(TakeTo)和带回的车数(TakeBack),与最佳路径的这两个值比较即可。

关于DFS遍历最短路径

DFS(s,t)
push(s)
foreach v in neighborhood of s
if v==t
push(v)
continue
else
DFS(v,t)
pop()
end


A1018代码:
#include<iostream>
#include<vector>

using namespace std;

#define INF 0x6FFFFFFF

struct Edge
{
int v,dist;
Edge(int _v,int _dist):v(_v),dist(_dist){}
};
struct Node
{
int dist;
bool visited;
int c;
vector<int> pre;
};

vector<Node> city;
vector<vector<Edge>> G;

vector<int>bPath;//best path
vector<int>cPath;//current path
int bTakeTo=0,bTakeBack=0,cTakeTo=0,cTakeBack=0;
vector<int>::reverse_iterator rit;
//vector<int> DFSPath;
int cmax;//max capacity of each station
int n;//vertexs
int sp;//target station
int m;//edges
int hfull;

void Dijkstra(int s,int t)
{
for(int i=0;i<=n;i++)
{
city[i].visited=false;
city[i].dist=INF;
}
city[s].dist=0;

while(true)
{
//find min
int index=-1;
int mindist=INF;
for(int i=0;i<=n;i++)
{
if(city[i].dist<mindist && !city[i].visited)
{
index=i;
mindist=city[i].dist;
}
}
if(index==-1)
return ;
city[index].visited=true;

//scan the neighborhood
for(int i=0;i<G[index].size();i++)
{
int v=G[index][i].v;
if(!city[v].visited)
{
if(city[v].dist>(city[index].dist+G[index][i].dist))
{
city[v].pre.clear();
city[v].pre.push_back(index);
city[v].dist=city[index].dist+G[index][i].dist;
}
else if(city[v].dist==(city[index].dist+G[index][i].dist))
{
city[v].pre.push_back(index);
}
}
}
}
return ;
}
void findBestPath(int s,int t)
{
cPath.push_back(t);
for(int i=0;i<city[t].pre.size();i++)
{
int v=city[t].pre[i];
if(v!=s)
{
findBestPath(s,v);
}
else
{
if(bPath.empty())
{
//update best path info
bPath.assign(cPath.begin(),cPath.end());
for(rit=bPath.rbegin();rit!=bPath.rend();rit++)
{
if(city[*rit].c<hfull)
{
if(bTakeBack>hfull-city[*rit].c)
{
bTakeBack-=hfull-city[*rit].c;
}
else if(bTakeBack>0)
{
bTakeTo+=hfull-city[*rit].c-bTakeBack;
bTakeBack=0;
}
else
{
bTakeTo+=hfull-city[*rit].c;
}
}
else if(city[*rit].c>hfull)
{
bTakeBack+=city[*rit].c-hfull;
}
}

}
else
{
//calculate cTakeTo & cTakeBack
for(rit=cPath.rbegin();rit!=cPath.rend();rit++)
{
if(city[*rit].c<hfull)
{
if(cTakeBack>hfull-city[*rit].c)
cTakeBack-=hfull-city[*rit].c;
else if(cTakeBack>0)
{
cTakeTo+=hfull-city[*rit].c-cTakeBack;
cTakeBack=0;
}
else
cTakeTo+=hfull-city[*rit].c;
}
else if(city[*rit].c>hfull)
{
cTakeBack+=city[*rit].c-hfull;
}
}
//compare cPath & bPath
if(bTakeTo>cTakeTo || (bTakeTo==cTakeTo && bTakeBack>cTakeBack))
{
bTakeTo=cTakeTo;
bTakeBack=cTakeBack;
bPath.assign(cPath.begin(),cPath.end());

}
}
//clear current path info
continue;
cTakeTo=0;
cTakeBack=0;
}

}
cPath.pop_back();
cTakeTo=0;
cTakeBack=0;
return ;
}

int main()
{
cin>>cmax>>n>>sp>>m;
hfull=cmax/2;
//init
city.clear();
city.resize(n+1);
for(int i=1;i<=n;i++)
cin>>city[i].c;
int a,b,c;
G.clear();
G.resize(n+1);
for(int i=0;i<m;i++)
{
cin>>a>>b>>c;
G[a].push_back(Edge(b,c));
G[b].push_back(Edge(a,c));
}
int s=0,t=sp;
//Dijkstra
Dijkstra(s,t);

cPath.clear();
bPath.clear();
//DFS
findBestPath(s,t);
cout<<bTakeTo<<" ";
cout<<s<<"->";
for(int i=bPath.size()-1;i>0;i--)
cout<<bPath[i]<<"->";
cout<<t<<" ";
cout<<bTakeBack;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: