算法与数据结构
采用无向图多重邻接表的存储结构。顶点结点表示城市,包括城市的第一条边,拥有的救援队数量,最短路径值,是否已经访问,最短路径的条数,最大救援队的数量。
迪杰斯特拉算法,做一点小小的增加就可以。对于多条路径的问题,比较新迭代操作计算的路径与源路径,如果小于源路径,就更改路径最短值,如果等于最短路径值,就增加路径的数量,新路径数量 = 源路径数量+当前前驱节点的路径数量。最大救援队是类似的,如果:
当前前驱节点最大救援队数量+当前节点救援队数量>当前节点最大救援队数量
就更改当前最大救援队数量。
代码
#include <iostream>
#include <memory.h>
#include <stack>
using namespace std;
typedef struct ARC{
int c1, c2;
int dis;
struct ARC * next1;
struct ARC * next2;
}ARC;
typedef struct CITY{
int rescue;
int roadnum;//距离源点的路径数量
int maxrescue;
int mindis;
bool visit;
ARC *firstarc;
}CITY;
void Dijkstra(int start, int desti, CITY *city, int citynum)
{
/*vnum*/
int vnum;
vnum = 1;
/*迭代一次的操作包括,计算新包括进来的值*/
int newnode = start;
city[start].maxrescue = city[start].rescue;
city[start].roadnum = 1;
int minestdis = 0;
while(vnum<citynum && newnode != desti){
city[newnode].visit = true;
ARC * next = city[newnode].firstarc;
int minnode;
while(next){//在newnode的边中计算未包含进来的点的最短路径估计值
int node, length;
if(next->c1==newnode) node = next->c2, length = next->dis, next = next->next1;
else if(next->c2==newnode) node = next->c1, length = next->dis, next = next->next2;
if(city[node].visit == false){
if(city[node].mindis == 0 || city[node].mindis > city[newnode].mindis+length){
city[node].mindis = city[newnode].mindis+length;
city[node].roadnum = city[newnode].roadnum;
city[node].maxrescue = city[newnode].maxrescue + city[node].rescue;
}
else if(city[node].mindis == city[newnode].mindis + length){//解决多条最短路径的问题
city[node].roadnum += city[newnode].roadnum;
if(city[node].maxrescue < city[newnode].maxrescue + city[node].rescue)
city[node].maxrescue = city[newnode].maxrescue + city[node].rescue;
}
}
}//end while
minestdis = 0;
for(int j=0;j<citynum;j++){
if(city[j].visit == false &&(minestdis == 0 || (city[j].mindis && city[j].mindis <= minestdis)) )
minestdis = city[j].mindis, minnode = j;
}
newnode = minnode;//最小的那个点极为下一次迭代计算的源点
vnum++;
}
}
int main1003()
{
int citynum, roadnum, start, desti;
cin>>citynum>>roadnum>>start>>desti;
CITY city[citynum];
memset(city, 0, sizeof(CITY)*citynum);
for(int i=0;i<citynum;i++){
cin>>city[i].rescue;
}
for(int i=0;i<roadnum;i++){
ARC *curarc = (ARC *)malloc(sizeof(ARC));
cin>>curarc->c1>>curarc->c2>>curarc->dis;
curarc->next1 = city[curarc->c1].firstarc;
curarc->next2 = city[curarc->c2].firstarc;
city[curarc->c1].firstarc = curarc;
city[curarc->c2].firstarc = curarc;
}
Dijkstra(start, desti, city, citynum);
cout<<city[desti].roadnum<<' '<<city[desti].maxrescue;
return 0;
}