路径存在
对一个包含 N 个顶点的有向图 G(V, E) 用邻接表进行存储,其中顶点以数组保存。对于该有向图类 adjListGraph,
要求增加一个成员函数 existPath,对于图中的任两个顶点 i, j,检查它们之间是否有路径存在。如有,输出其中最小的一条路径。
如无,输出字符串 "false"。(40')
对于最小路径,首先判断长度,输出较小长度的路径,若存在多条长度相同的路径,则输出路径顺序中结点编号较小的路径。例如路径 6 1 5 4 和 6 2 3 4,应选择前者输出。
注:图中可能存在环。
要求:在文件头部说明新增成员函数的设计思路,并分析时间复杂度分析。(10')
输入描述
第1行输入顶点个数 N,N 为正整数。
第2行输入有向边信息,边的起点和终点分别为顶点的编号,编号间以逗号相隔,边之间以空格相隔。
第3行输入路径起点和终点的编号,以空格相隔。
输出描述
输出路径检查的结果。
输入举例
6
1,3 2,3 1,4 3,5 2,5 4,2 5,6 3,6
4 6
输出举例
4 2 3 6
#include<bits/stdc++.h>
using namespace std;
template<class elemType>
class linkQueue
{
private:
struct node
{
elemType data;
node *next;
node( elemType &x,node *N=NULL)
{
data=x;
next=N;
}
node():next(NULL){}
~node(){}
};
node *front,*rear;
public:
linkQueue();
~linkQueue();
bool isEmpty() ;
elemType deQueue();
void enQueue( elemType &x);
};
template<class elemType>
bool linkQueue<elemType>::isEmpty()
{
return front==NULL;
}
template<class elemType>
linkQueue<elemType>::linkQueue()
{
front=rear=NULL;
}
template<class elemType>
linkQueue<elemType>::~linkQueue()
{
node *tmp;
while(front!=NULL)
{
tmp=front;
front=front->next;
delete tmp;
}
}
template<class elemType>
void linkQueue<elemType>::enQueue(elemType &x)
{
if(rear==NULL)
front=rear=new node(x);
else
rear=rear->next=new node(x);
}
template<class elemType>
elemType linkQueue<elemType>::deQueue()
{
node *tmp=front;
elemType value=front->data;
front=front->next;
if(front==NULL)
rear=NULL;
delete tmp;
return value;
}
template<class TypeOfVer,class TypeOfEdge>
class adjListGraph
{
public:
adjListGraph(int vSize);
void insert(TypeOfVer x,TypeOfVer y,TypeOfEdge w);
//void remove(TypeOfVer x,TypeOfVer y);
//bool exist(TypeOfVer x,TypeOfVer y)const;
bool checkRoute(int start,int end);
//void existPath(int start,int end);
//~adjListGraph();
void unweightedShortDistance(TypeOfVer start,TypeOfVer end,TypeOfEdge noEdge);
private:
int Vers,Edges;
struct edgeNode
{
int end;
TypeOfEdge weight;
edgeNode *next;
edgeNode(int e,TypeOfEdge w,edgeNode *n=NULL)
{
end=e;
weight=w;
next=n;
}
};
struct verNode
{
TypeOfVer ver;
edgeNode *head;
verNode(edgeNode *h=NULL)
{
head=h;
}
};
verNode *verList;
int find(TypeOfVer v)const
{
for(int i=0;i<Vers;i++)
{
if(verList[i].ver==v)
{
return i;
}
}
}
bool checkRoute(int start,int end,bool visited[]);
//void existPath(int start,int end,bool visited[]);
void printPath(int start,int end,int prev[]);
};
template<class TypeOfVer,class TypeOfEdge>
adjListGraph<TypeOfVer,TypeOfEdge>::adjListGraph(int vSize)
{
Vers=vSize;
Edges=0;
verList=new verNode[vSize];
for(int i=0;i<Vers;i++)
{
verList[i].ver=i+1;
}
}
/*template<class TypeOfVer,class TypeOfEdge>
adjListGraph<TypeOfVer,TypeOfEdge>::~adjListGraph()
{
int i;
edgeNode *p;
for(i=0;i<Vers;i++)
{
while((p=verList[i].head)!=NULL)
{
verList[i].head=p->next;
delete p;
}
}
delete []verList;
}*/
template<class TypeOfVer,class TypeOfEdge>
void adjListGraph<TypeOfVer,TypeOfEdge>::insert(TypeOfVer x,TypeOfVer y,TypeOfEdge w)
{
int u=find(x);
int v=find(y);
verList[u].head=new edgeNode(v,w,verList[u].head);
++Edges;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjListGraph<TypeOfVer,TypeOfEdge>::checkRoute(int start,int end)
{
bool *visited=new bool[Vers];
int startNo,endNo;
for(int i=0;i<Vers;i++)
{
visited[i]=false;
}
for(startNo=0;startNo<Vers;startNo++)
{
if(verList[startNo].ver==start)break;
}
//if(startNo==Vers)return false;
for(endNo=0;endNo<Vers;endNo++)
{
if(verList[endNo].ver==end)break;
}
//if(endNo==Vers)return false;
return checkRoute(startNo,endNo,visited);
}
template<class TypeOfVer,class TypeOfEdge>
bool adjListGraph<TypeOfVer,TypeOfEdge>::checkRoute(int start,int end,bool visited[])
{
edgeNode *p=verList[start].head;
bool flag=0;
visited[start]=true;
while(p!=NULL)
{
if(p->end==end)return true;
if(!visited[p->end])
{
flag=checkRoute(p->end,end,visited);
if(flag)return true;
}
p=p->next;
}
//cout<<"okok";
return false;
}
/*template<class TypeOfVer,class TypeOfEdge>
void adjListGraph<TypeOfVer,TypeOfEdge>::existPath(int start,int end)
{
bool *visited=new bool[Vers];
for(int i=0;i<Vers;i++)
{
visited[i]=false;
}
existPath(start,end,visited);
}
static int L[100],o=0;
template<class TypeOfVer,class TypeOfEdge>
void adjListGraph<TypeOfVer,TypeOfEdge>::existPath(int start,int end,bool visited[])
{
edgeNode *p=verList[start].head;
L[o]=start;
o++;
//cout<<start;
visited[start]=true;
while(p!=NULL)
{
if(p->end==end)
{
L[o]=end;
o++;
//cout<<"okok";
break;
}
else if(!visited[p->end]&&checkRoute(p->end,end))
{
existPath(p->end,end,visited);
}
p=p->next;
}
}*/
template<class TypeOfVer,class TypeOfEdge>
void adjListGraph<TypeOfVer,TypeOfEdge>::unweightedShortDistance(TypeOfVer start,TypeOfVer end,TypeOfEdge noEdge)
{
linkQueue<int> q;
TypeOfEdge *distance=new TypeOfEdge[Vers];
int *prev=new int[Vers];
int u,sNo;
edgeNode *p;
for(int i=0;i<Vers;i++)
{
distance[i]=noEdge;
}
sNo=find(start);
distance[sNo]=0;
prev[sNo]=sNo;
q.enQueue(sNo);
while(!q.isEmpty())
{
u=q.deQueue();
for(p=verList[u].head;p!=NULL;p=p->next)
{
if(distance[p->end]==noEdge)
{
distance[p->end]=distance[u]+1;
prev[p->end]=u;
q.enQueue(p->end);
}
}
}
//cout<<prev[6]<<endl;
printPath(sNo,end-1,prev);
}
template<class TypeOfVer,class TypeOfEdge>
void adjListGraph<TypeOfVer,TypeOfEdge>::printPath(int start,int end,int prev[])
{
if(start==end)
{
cout<<verList[start].ver;
return;
}
printPath(start,prev[end],prev);
cout<<' '<<verList[end].ver;
}
//int **Arr;
int main()
{
int n;
cin>>n;
string str;
getline(cin,str);
getline(cin,str);
//cout<<str;
int x,y;
cin>>x>>y;
//cout<<x<<y;
adjListGraph<int,int> A(n);
int k=0;
for(int i=0;i<str.size();i++)
{
if(str[i]==',')
{
k++;
}
}
//cout<<k;
for(int i=0;i<k;i++)
{
int t1,t2,u,v;
u=4*i;v=4*i+2;
t1=str[u]-'0';
t2=str[v]-'0';
//cout<<t1<<" "<<t2<<endl;
A.insert(t1,t2,0);
}
bool flg=A.checkRoute(x,y);
//cout<<flg;
if(flg)
{
A.unweightedShortDistance(x,y,-1);
}
else
{
cout<<"false";
}
}
这个是自己写的但是没有办法满足“若存在多条长度相同的路径,则输出路径顺序中结点编号较小的路径”
#include<bits/stdc++.h>
using namespace std;
vector<int> road[10001]; // 储存每个点能通向的其他点
vector<int> finds,key; // 查找过错 and 储存答案
bool flag = false; // 查找结果
bool op[10001]={false}; // 避免查询过程重复路径
void find_RoadMin(int x, int y);
int main()
{
int N,num,a,b; // 总点数,边个数,俩个边
cin >> N >> num;
// 数据读入
while (num--){
cin >> a >> b;
road[a].push_back(b);
// road[b].push_back(a); // 注意无向的话俩个顶点应该是互通的,可你这道题是不互通
}
// 开始查询
cin >> a >> b;
find_RoadMin(a,b);
// 答案输出
if(flag){
cout << key[0];
for(int z=1;z<key.size();z++) cout << " " << key[z];
}else cout << "false" << endl;
return 0;
}
void find_RoadMin(int x, int y){
if(op[x]) return;
op[x] = true;
finds.push_back(x);
if(x==y)
{
// cout<< "*****"; // 解开注释观察测试数据
if(finds.size()<key.size() || key.empty() ) {
key.assign(finds.begin(),finds.end()); // key复制finds
}
else if(finds.size()==key.size()){
for(int z=0;z<finds.size();z++){
if(key[z]==finds[z]) continue;
if(key[z]>finds[z]) key.assign(finds.begin(),finds.end()); // key下一个数比finds的大
break;
}
}
flag = true;
}
// 解开注释观察每次测试数据变换
// for(int z:finds) cout << z << " ";
// cout << endl;
for(int z:road[x]) find_RoadMin(z,y);
finds.pop_back();
op[x] = false;
}
/*路径存在
对一个包含 N 个顶点的有向图 G(V, E) 用邻接表进行存储,其中顶点以数组保存。对于该有向图类 adjListGraph,
要求增加一个成员函数 existPath,对于图中的任两个顶点 i, j,检查它们之间是否有路径存在。如有,输出其中最小的一条路径。
如无,输出字符串 "false"。(40')
对于最小路径,首先判断长度,输出较小长度的路径,若存在多条长度相同的路径,则输出路径顺序中结点编号较小的路径。例如路径 6 1 5 4 和 6 2 3 4,应选择前者输出。
注:图中可能存在环。
要求:在文件头部说明新增成员函数的设计思路,并分析时间复杂度分析。(10')
输入描述
第1行输入顶点个数 N,N 为正整数。
第2行输入有向边信息,边的起点和终点分别为顶点的编号,编号间以逗号相隔,边之间以空格相隔。
第3行输入路径起点和终点的编号,以空格相隔。
输出描述
输出路径检查的结果。
输入举例
6
1,3 1,4 3,5 2,5 4,2 5,6 2,3 3,6
4 6
输出举例
4 2 3 6
8
1,8 6,8 5,1 3,6 7,5 7,3
7 8
*/
#include<bits/stdc++.h>
using namespace std;
static int bvvd=0;
template<class elemType>
class linkQueue
{
private:
struct node
{
elemType data;
node *next;
node( elemType &x,node *N=NULL)
{
data=x;
next=N;
}
node():next(NULL){}
~node(){}
};
node *front,*rear;
public:
linkQueue();
~linkQueue();
bool isEmpty() ;
elemType deQueue();
void enQueue( elemType &x);
};
template<class elemType>
bool linkQueue<elemType>::isEmpty()
{
return front==NULL;
}
template<class elemType>
linkQueue<elemType>::linkQueue()
{
front=rear=NULL;
}
template<class elemType>
linkQueue<elemType>::~linkQueue()
{
node *tmp;
while(front!=NULL)
{
tmp=front;
front=front->next;
delete tmp;
}
}
template<class elemType>
void linkQueue<elemType>::enQueue(elemType &x)
{
if(rear==NULL)
front=rear=new node(x);
else
rear=rear->next=new node(x);
}
template<class elemType>
elemType linkQueue<elemType>::deQueue()
{
node *tmp=front;
elemType value=front->data;
front=front->next;
if(front==NULL)
rear=NULL;
delete tmp;
return value;
}
template<class TypeOfVer,class TypeOfEdge>
class adjListGraph
{
public:
adjListGraph(int vSize);
void insert(TypeOfVer x,TypeOfVer y,TypeOfEdge w);
//void remove(TypeOfVer x,TypeOfVer y);
//bool exist(TypeOfVer x,TypeOfVer y)const;
bool checkRoute(int start,int end);
//void existPath(int start,int end);
//~adjListGraph();
int unweightedShortDistance(TypeOfVer start,TypeOfVer end,TypeOfEdge noEdge);
private:
int Vers,Edges;
struct edgeNode
{
int end;
TypeOfEdge weight;
edgeNode *next;
edgeNode(int e,TypeOfEdge w,edgeNode *n=NULL)
{
end=e;
weight=w;
next=n;
}
};
struct verNode
{
TypeOfVer ver;
edgeNode *head;
verNode(edgeNode *h=NULL)
{
head=h;
}
};
verNode *verList;
int find(TypeOfVer v)const
{
for(int i=0;i<Vers;i++)
{
if(verList[i].ver==v)
{
return i;
}
}
}
bool checkRoute(int start,int end,bool visited[]);
//void existPath(int start,int end,bool visited[]);
void printPath(int start,int end,int prev[]);
};
template<class TypeOfVer,class TypeOfEdge>
adjListGraph<TypeOfVer,TypeOfEdge>::adjListGraph(int vSize)
{
Vers=vSize;
Edges=0;
verList=new verNode[vSize];
for(int i=0;i<Vers;i++)
{
verList[i].ver=i+1;
}
}
/*template<class TypeOfVer,class TypeOfEdge>
adjListGraph<TypeOfVer,TypeOfEdge>::~adjListGraph()
{
int i;
edgeNode *p;
for(i=0;i<Vers;i++)
{
while((p=verList[i].head)!=NULL)
{
verList[i].head=p->next;
delete p;
}
}
delete []verList;
}*/
template<class TypeOfVer,class TypeOfEdge>
void adjListGraph<TypeOfVer,TypeOfEdge>::insert(TypeOfVer x,TypeOfVer y,TypeOfEdge w)
{
int u=find(x);
int v=find(y);
verList[u].head=new edgeNode(v,w,verList[u].head);
++Edges;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjListGraph<TypeOfVer,TypeOfEdge>::checkRoute(int start,int end)
{
bool *visited=new bool[Vers];
int startNo,endNo;
for(int i=0;i<Vers;i++)
{
visited[i]=false;
}
for(startNo=0;startNo<Vers;++startNo)
{
if(verList[startNo].ver==start)break;
}
if(startNo==Vers)
{
//cout<<"okok";
return false;
}
//if(start>Vers)return false;
for(endNo=0;endNo<Vers;++endNo)
{
if(verList[endNo].ver==end)break;
}
if(endNo==Vers)
{
//cout<<"okok";
return false;
}
//if(end>Vers)return false;
return checkRoute(startNo,endNo,visited);
}
template<class TypeOfVer,class TypeOfEdge>
bool adjListGraph<TypeOfVer,TypeOfEdge>::checkRoute(int start,int end,bool visited[])
{
edgeNode *p=verList[start].head;
bool flag=0;
visited[start]=true;
while(p!=NULL)
{
if(p->end==end)
{
//cout<<"okok";
return true;
}
if(!visited[p->end])
{
flag=checkRoute(p->end,end,visited);
if(flag)return true;
}
p=p->next;
}
//cout<<"okok";
return false;
}
/*template<class TypeOfVer,class TypeOfEdge>
void adjListGraph<TypeOfVer,TypeOfEdge>::existPath(int start,int end)
{
bool *visited=new bool[Vers];
for(int i=0;i<Vers;i++)
{
visited[i]=false;
}
existPath(start,end,visited);
}
static int L[100],o=0;
template<class TypeOfVer,class TypeOfEdge>
void adjListGraph<TypeOfVer,TypeOfEdge>::existPath(int start,int end,bool visited[])
{
edgeNode *p=verList[start].head;
L[o]=start;
o++;
//cout<<start;
visited[start]=true;
while(p!=NULL)
{
if(p->end==end)
{
L[o]=end;
o++;
//cout<<"okok";
break;
}
else if(!visited[p->end]&&checkRoute(p->end,end))
{
existPath(p->end,end,visited);
}
p=p->next;
}
}*/
template<class TypeOfVer,class TypeOfEdge>
int adjListGraph<TypeOfVer,TypeOfEdge>::unweightedShortDistance(TypeOfVer start,TypeOfVer end,TypeOfEdge noEdge)
{
if(!checkRoute(start,end+1))
{
return -1;
}
linkQueue<int> q;
TypeOfEdge *distance=new TypeOfEdge[Vers];
int *prev=new int[Vers];
for(int i=0;i<Vers;i++)
{
prev[i]=10000000;
}
int u,sNo;
edgeNode *p;
for(int i=0;i<Vers;i++)
{
distance[i]=noEdge;
}
sNo=find(start);
distance[sNo]=0;
prev[sNo]=sNo;
q.enQueue(sNo);
while(!q.isEmpty())
{
u=q.deQueue();
for(p=verList[u].head;p!=NULL;p=p->next)
{
if(distance[p->end]==noEdge||distance[p->end]>=distance[u]+1)
{
distance[p->end]=distance[u]+1;
if(prev[p->end]>u)
{
prev[p->end]=u;
}
q.enQueue(p->end);
}
}
}
//cout<<prev[5]<<endl;
bvvd=0;
printPath(sNo,end,prev);
return bvvd;
}
template<class TypeOfVer,class TypeOfEdge>
void adjListGraph<TypeOfVer,TypeOfEdge>::printPath(int start,int end,int prev[])
{
if(start==end)
{
//cout<<verList[start].ver;
bvvd++;
return;
}
printPath(start,prev[end],prev);
//cout<<' '<<verList[end].ver;
bvvd++;
}
//int **Arr;
int main()
{
int n;
cin>>n;
int **Arr;
Arr=new int*[n];
for(int i=0;i<n;i++)
{
Arr[i]=new int[n];
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
Arr[i][j]=0;
}
}
string str;
getline(cin,str);
getline(cin,str);
//cout<<str;
int x,y;
cin>>x>>y;
//cout<<x<<y;
if(x==y)
{
cout<<x;
return 0;
}
adjListGraph<int,int> A(n);
int k=0;
for(int i=0;i<str.size();i++)
{
if(str[i]==',')
{
k++;
}
}
//cout<<k;
int u=0,v=0,t=0;
for(int i=0;i<k;i++)
{
int t1=0,t2=0;
for(int j=0;str[u+j]!=',';j++)
{
t1=t1*10+str[u+j]-'0';
t=j;
}
//cout<<t;
v=u+t+2;
//cout<<v;
for(int j=0;str[v+j]<='9'&&str[v+j]>='0';j++)
{
//cout<<str[v+j];
t2=t2*10+str[v+j]-'0';
t+=j;
}
t=t+4;
//cout<<t<<"okok";
//cout<<t1<<" "<<t2<<endl;
A.insert(t1,t2,0);
Arr[t1-1][t2-1]=1;
u=u+t;
t=0;
}
bool flg=A.checkRoute(x,y);
//cout<<flg;
/*for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cout<<Arr[i][j]<<' ';
}
cout<<endl;
}*/
if(flg)
{
int bk=A.unweightedShortDistance(x,y-1,-1);
//cout<<"bk:"<<bk<<endl;
int q=x-1;
cout<<x<<' ';
bk--;
for(int i=0;i<n;i++)
{
if(Arr[q][y-1]==1)
{
cout<<y;
return 0;
}
int R=A.unweightedShortDistance(i+1,y-1,-1);
//cout<<"R:"<<R<<endl;
//cout<<"bk:"<<bk<<endl;
if(Arr[q][i]==1&&A.checkRoute(i+1,y)&&R==bk)
{
//cout<<"okok";
cout<<i+1<<' ';
q=i;
i=-1;
bk--;
}
}
}
else
{
cout<<"false";
}
return 0;
}
用后面输出邻接矩阵处理的,似乎没bug了