SJTU简单路径数目

Description
大家还记得邻接表类吗?没错,邻接表是表示稀疏图(边数比较少的图)的一种很好的数据结构。

现在,我们要求使用深度优先遍历的思想,利用邻接表类,对给定的有向图,找出从指定结点start出发,长度为M的所有简单路径(简单路径是顶点序列中顶点不重复出现的路径)的数量。

为简化题目,我们还是约定:用正整数1,2,3……n来表示每个结点的ID(编号)。(输入可能有重边)

Input Format
第1行:n m start M //正整数n ,代表图中结点的数量。非负整数m代表要图中有向边的数量。start为起点编号,M为题中的简单路径长度

第2行到第1+m行: a b //每行两个整数:代表结点a到结点b有一条有向边(a->b)

Output Format
一个整数k,代表长度为M的所有简单路径的数量

Sample Input1
5 4 1 2
1 2
2 3
3 4
4 5
Sample Output1
1 //从1出发,长度为2的简单路径只有一条:1->2->3
Sample Input2
6 5 1 2
1 2
2 3
2 4
2 1
5 6
Sample Output2
2 //从1出发,长度为2的简单路径有2条:1->2->3,1->2->4。1->2->1不是,因为不是简单路径。
Limits
0<n,M<=10 0<=m<=100

数据保证合法

(PS:关于简单路径的起点终点是否能相同,这个有点争议。本题规定不能相同)

#include <iostream>
using namespace std;

template <class TypeOfVer, class TypeOfEdge>
class adjListGraph
{
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;
			else return 
	}
	void dfs(int start, int M, int& top, bool visited[], int st[], int& count)const;
public:
	adjListGraph(int vSize);
	void insert(TypeOfVer x, TypeOfVer y, TypeOfEdge w);
	void dfs(int start, int M)const;
	~adjListGraph();
};

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>
void adjListGraph<TypeOfVer, TypeOfEdge>::insert(TypeOfVer x, TypeOfVer y, TypeOfEdge w)
{
	int u = find(x), v = find(y);
	verList[u].head = new edgeNode(v, w, verList[u].head);
	++Edges;
}
template <class TypeOfVer, class TypeOfEdge>
void adjListGraph<TypeOfVer, TypeOfEdge>::dfs(int start, int M)const
{
	bool* visited = new bool[Vers];
	int* stack = new int[M], top = 0, count = 0;
	for (int i = 0; i < Vers; ++i) visited[i] = false;
	dfs(start - 1, M, top, visited, stack,count);
	cout << count;
}

template <class TypeOfVer, class TypeOfEdge>
void adjListGraph<TypeOfVer, TypeOfEdge>::dfs(int start, int M, int &top, bool visited[], int st[],int &count)const
{
	edgeNode* p = verList[start].head;
	visited[start] = true;
	st[top++] = start;
	if (top == M + 1) count++;
	else { 
		while (p!=NULL) {
		if(!visited[p->end])
			dfs(p->end, M, top, visited, st, count);
		p = p->next;
		}
	}
	visited[start] = false;
	--top;
}

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;
}

int main()
{
	int n, m, start, M;
	cin >> n >> m >> start >> M;
	adjListGraph<int, int > A(n);
	for (int i = 0; i < m; ++i) {
		int x, y;
		cin >> x >> y;
		A.insert(x, y, 1);
	}
	A.dfs(start, M);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值