|
错一半的用例,有空再检查吧
检测了半天,修改了一些问题后,还是没通过,唉,说起来都是泪啊。
题目也没说清楚一些问题。唉,改了很多东西,却没有多通过一个用例。
#include <map>
#include <set>
using namespace std;
struct stop{
unsigned int next[100];//最大有100个下一站,可连通
bool paased;//每次前往下一战时,先判断下一站是否已通过,若为通过则将其加入oldstop
int nnum;//可连通数量
int lnum;//线路数量
unsigned int LineNo[100];//所在线路的id
unsigned int path[100][100];//对于每条路径。。。我只保存前一个值是不够的。。。可能有多条路径,最多100条
int pnum;//路径数量
//int paassN;//
};
map<unsigned int,stop> allstop;
unsigned int oldstop[1000];
unsigned int newos[1000];//用来替换正在计算中的起点站
int newosn;//总起点暂时总数
int oldn;//起点总数
int passN;//结果站点总数
//int ps;//路径总数
//int newps;//新路径暂时总数
//unsigned int path[1000][100];
//unsigned int npath[1000][100];
/*******************************************************************************************************************
函数说明: 增加某条地铁线路
函数原型: void AddLine(unsigned int LineNo, unsigned int StationNum ,unsigned int *pStationArray);
输入参数:
LineNo 地铁线路号;
StationNum 该条地铁线中的站点数目,由调用者保证不小于2;
pStationArray 该条地铁线的所有站点信息,pStationArray指向的存储空间在函数外会被释放,请自行申请存储空间;
输出参数: 无
返回值 : 无
********************************************************************************************************************/
void AddLine(unsigned int LineNo, unsigned int StationNum ,unsigned int *pStationArray)
{
/* 在这里实现功能 */
//假设,对与 1 ,2, 1的环线线路,如何进行判断,站台数是2。。。
unsigned int p = 0 ;
unsigned int start = *pStationArray;
unsigned int before = *pStationArray;
map<unsigned int,stop>::iterator t;
for(int i = 0 ; i < StationNum ; i++){
if(allstop.count(*pStationArray)){//如果与其他线路交叉
t = allstop.find(*pStationArray);
t->second.LineNo[t->second.lnum++] = LineNo ;
if( i == 0){
before = *pStationArray++;
continue;
}
}else{
stop news;
news.LineNo[0] = LineNo ;
news.lnum = 1;
news.paased = false;
news.nnum = 0;
news.pnum = 0;
allstop.insert(pair<unsigned int,stop>(*pStationArray , news));
}
if(i > 0){
t = allstop.find(before);
t->second.next[t->second.nnum++] = *pStationArray;
t = allstop.find(*pStationArray) ;
t->second.next[t->second.nnum++] = before;
}
before = *pStationArray++;
}
if( start == *pStationArray) {//即为环,这里的stationnum是多少就是多少,不重复包含初始站和终点站
t->second.next[t->second.nnum++] = start ;
t = allstop.find(start);
t->second.next[t->second.nnum++] = before ;
}
return;
}
/*********************************************************************************************************************
函数说明:计算从起点站到终点站的最短路线长度
函数原型:int CalcMinPathLen(unsigned int SrcStation, unsigned int DesStation);
输入参数:
SrcStation 起点站;
DesStation 终点站;
输出参数:无
返回值 :
起点站到终点站的最短路线长度
-1:任何出错情况(包括路线不存在、站点不存在、起点和终点重叠等等)
**********************************************************************************************************************/
bool gonext(unsigned int DesStation){
map<unsigned int,stop>::iterator p;
map<unsigned int,stop>::iterator next;
newosn=0;
passN++;
//newps=0;
for(int i=0;i<oldn;i++){
p =allstop.find(oldstop);
for(int j=0;j<p->second.nnum;j++){
next = allstop.find(p->second.next[j]);
if(!next->second.paased){
//next->second.paased = true;//一次前进过程中,可以从不同的方向到达同一点,但是,不能从回到原来的点
int pathnun=p->second.pnum;
for(int l=0;l<pathnun;l++){
for(int k=0;k < passN - 1;k++){
next->second.path[next->second.pnum][k] = p->second.path[l][k];
}
next->second.path[next->second.pnum++][passN-1] = next->first;
//npath[newps][passN-1] = next->first;
//next->second.path[next->second.pnum++] = path[newps++];
}
//next
newos[newosn++] = next->first;
}
}
}
oldn = newosn;
//ps = newps;
int nn=0;
for(int i=0;i < oldn;i++){
p = allstop.find(newos);
if(!p->second.paased){
oldstop[nn++] = newos ;
p->second.paased= true ;
}
}
oldn = nn;
//for (int i=0;i < ps;i++){
//for(int j=0;j < passN ;j++){
//path[j] = npath[j];
//}
//}
for (int i=0;i<oldn;i++){
if(oldstop == DesStation)
return false;
}
return true;
}
int CalcMinPathLen(unsigned int SrcStation, unsigned int DesStation)
{
/* 在这里实现功能 */
if(SrcStation==DesStation)return -1;
if(!allstop.count(SrcStation)||!allstop.count(DesStation))return -1;
map<unsigned int ,stop>::iterator p;
p = allstop.begin();
for(int i=0; i< allstop.size();i++){//初始化一部分数据
p -> second.paased = false;
p -> second.pnum = 0;
p++;
}
p = allstop.find(SrcStation );
p->second.paased = true;
p->second.pnum=1;
oldn = 0;
oldstop[oldn++] = SrcStation ;
//path[0][0] = SrcStation;
passN = 0;
//ps = 0;
while(gonext(DesStation));//寻找路径
p = allstop.find(DesStation);
int k =0;
int m =0 ;
int fuc = p->second.pnum ;
unsigned int fuck[100];
///*
for(int L =0;L < p->second.pnum;L++){
fuc --;
for(int i = 0;i < fuc;i++){//还要字典序排序?
if( p->second.path[k] > p ->second.path[i+1][k]){
for( m=0;m<passN;m++)
fuck[m] = p->second.path[m];
for( m =0; m<passN;m++)
p->second.path[m] = p->second.path[i+1][m];
for( m =0;m<passN;m++)
p->second.path[i+1][m] = fuck[m];
}else{
for ( int ff=0;ff< passN;ff++){
if( p->second.path[k] > p ->second.path[i+1][k]){
for( m=0;m<passN;m++)
fuck[m] = p->second.path[m];
for( m =0; m<passN;m++)
p->second.path[m] = p->second.path[i+1][m];
for( m =0;m<passN;m++)
p->second.path[i+1][m] = fuck[m];
break;
}
}
}
}
}//*/
return passN;
}
/**********************************************************************************************************
函数说明:输出从起点站到终点站的最短路线
函数原型:int SearchMinPathes(unsigned int SrcStation,
unsigned int DesStation,
unsigned int* pPathNum,
unsigned int* pPathLen,
unsigned int **ppPathes);
输入参数:
SrcStation 起点站;
DesStation 终点站;
Output Param
pPathNum 最短路线条数;
pPathLen 最短路线长度;
ppPathes 存储最短路线的内存地址,内存空间在本函数内申请,调用者释放,内存空间的存储格式请见PPT要求;
返回值 :
0 :成功
-1:任何出错情况(包括路线不存在、站点不存在、起点和终点重叠等等)
************************************************************************************************************/
int SearchMinPathes(unsigned int SrcStation,
unsigned int DesStation,
unsigned int* pPathNum,
unsigned int* pPathLen,
unsigned int **ppPathes)
{
/* 在这里实现功能 */
map<unsigned int,stop>::iterator p;
int r = CalcMinPathLen(SrcStation,DesStation);
if(r==-1)return -1;
else{
*pPathNum = passN;
p = allstop.find(DesStation);
r = p->second.pnum;
*pPathLen = r;
//r*=passN;
unsigned int *save = (unsigned int*)malloc(sizeof(unsigned int)*r*passN);
*ppPathes = save;
for(int i=0;i<r;i++){
for(int j=0;j<passN;j++)
*save++ = p->second.path[j];
}
}
return 0;
}
/*************************************************************************************************
函数说明:输出从起点站到终点站的最优路线
函数原型:int SearchBestPathes(unsigned int SrcStation,
unsigned int DesStation,
unsigned int *pPathNum,
unsigned int* pPathLen,
unsigned int** ppPathes);
输入参数:
SrcStation 起点站;
DesStation 终点站;
Output Param
pPathNum 最优路线条数;
pPathLen 最短路线长度;
ppPathes 存储最短路线的内存地址,内存格式见下图,内存空间在本函数内申请,调用者释放;
返回值 :
0:成功
-1:任何出错情况(包括路线不存在、站点不存在、起点和终点重叠等等)
**************************************************************************************************/
int SearchBestPathes(unsigned int SrcStation,
unsigned int DesStation,
unsigned int *pPathNum,
unsigned int* pPathLen,
unsigned int** ppPathes)
{
/* 在这里实现功能 */
int mini = 999;//最短路线
int changes = 0;
int all = 0;
int pathnum = 0 ;
int pathchange[100];
set<unsigned int> oldline;
set<unsigned int>::iterator t;
map<unsigned int,stop>::iterator p;
map<unsigned int,stop>::iterator last;
map<unsigned int,stop>::iterator now;
map<unsigned int,stop>::iterator start;
int r = CalcMinPathLen(SrcStation,DesStation);\
if(r == -1)return -1;
else{
p = allstop.find(DesStation);
start = allstop.find(SrcStation);
all = p->second.pnum;
for(int i=0;i<all;i++){
last = start;
changes = 0;
for(int j=0;j<last->second.lnum;j++){
oldline.insert(last->second.LineNo[j]);//将第一个点可能的线路记录下来
}
for(int j=0;j<passN;j++){
now = allstop.find( p->second.path[j]);
int n = oldline.size();
t = oldline.begin();
bool htheline=false;
for (int k=0; k < n ;k++){
htheline = false ;
for(int m=0;m<now->second.lnum;m++){
if( *t == now->second.LineNo[m]){
htheline =true;
break;
}
}
if(!htheline){
t = oldline.erase(t);
}else{
t++;
}
}
if(oldline.size()==0){//为空时,即必须要换车了,将这个点的所有可能线路保存下来
changes++;
for(int j=0;j<last->second.lnum;j++){
for(int k=0;k<now->second.lnum;k++)
if(last->second.LineNo[j]==now->second.LineNo[k])
oldline.insert(last->second.LineNo[j]);//将从前一站到这一站可能使用的线路记录下来。
}
}else{
;//继续以剩余的线路继续前行
}
last = now;
}
pathchange = changes ;
oldline.clear();
}
mini = 999;
for(int i=0; i<all;i++){
mini = mini<pathchange?mini:pathchange;//编程之美
}
//oldline.clear();
for(int i=0;i<all;i++){
if(pathchange==mini)
pathchange[pathnum++] = i;//获得最佳路线的数量和序号
}
*pPathNum = pathnum;
*pPathLen = passN ;
unsigned int *save = (unsigned int*)malloc(sizeof(unsigned int)*pathnum*passN);
*ppPathes = save;
for(int i=0;i<pathnum;i++){
for(int j=0;j<passN;j++)
*save++ = p->second.path[pathchange][j];
}
}
return 0;
}
/*************************************************************************************************
函数说明:清空所有的线路信息
函数原型:void Clear();
输入参数:无
输出参数:无
返回值 :无
**************************************************************************************************/
void Clear()
{
/* 在这里实现功能 */
allstop.clear();
return ;
};
|
|
|