1. 程式人生 > >有向圖的最長路徑及是否存在環路結構

有向圖的最長路徑及是否存在環路結構

問題描述:

有n個長為m+1的字串,如果某個字串的最後m個字元與某個字串的前m個字元匹配,則兩個字串可以連線。問這n個字串最多可以連成一個多長的字串,如果出現迴圈,則返回錯誤。

分析:

把每個字串看成一個圖的頂點,兩個字串可以連線就形成一條有向邊。相當於判斷一個有向圖是否存在環以及求該有向圖的最長路徑。

可用圖的深度優先遍歷演算法來求解,圖用鄰接表表示。

1. 求解有向圖是否存在環及最長路徑

#define VERTEX_NUM	7
#define NOT_VISITED	-1	//該頂點未被訪問
#define VISITED		0	//該頂點已經被訪問,但它的鄰接點未被訪問完成
#define FINISHED	1	//結束訪問該頂點的鄰接表
#define IS_CIRCLE	-1

int maxLen = -1;
int getMaxLenInGraph(int adj[][VERTEX_NUM]); //返回-1表示該有向圖中存在環路
int DFS_VISTI(int state[], int adj[][VERTEX_NUM], int i, int *len); //深度優先遍歷	

int getMaxLenInGraph(int adj[][VERTEX_NUM])
{
	int state[VERTEX_NUM];

	for (int i = 0; i < VERTEX_NUM; i++)
		state[i] = NOT_VISITED;

	int tempLen;
	for (int i = 0; i < VERTEX_NUM; i++)
	{
		tempLen = 0;
		if (state[i] == NOT_VISITED)
		{
			if (DFS_VISTI(state, adj, i, &tempLen) == IS_CIRCLE)
				return IS_CIRCLE;
		}
	}

	return maxLen;
}

//state[i]儲存頂點i的狀態,adj[i][]陣列中儲存所有與頂點i相鄰的頂點
int DFS_VISTI(int state[], int adj[][VERTEX_NUM], int i, int *len)
{
	state[i] = VISITED;
	for (int j = 1; adj[i][j] != -1; j++)
	{
		if (state[adj[i][j]] == NOT_VISITED)			
		{
			(*len)++;
			if (DFS_VISTI(state, adj, adj[i][j], len) == IS_CIRCLE)
				return IS_CIRCLE;
		}
		else if (state[adj[i][j]] == VISITED)			//這樣表示環的存在,經得起考驗嗎?
		{
			*len = IS_CIRCLE;
			return IS_CIRCLE;
		}
	}
	state[i] = FINISHED;

	if (*len > maxLen)
		maxLen = *len;

	*len = 0;
	return 0;
}

測試程式碼:

int main()
{
	//圖的鄰接表資料,-1表示結束
	int Adj[VERTEX_NUM][VERTEX_NUM] = {
		{0, 1, 3, -1},
		{1, 2, 3, 4, -1},
		{2, 3, 4, 5, -1},
		{3, 4, -1},
		{4, 5, -1},
		{5, 6, -1},
		{6, -1}		//改為6, 0, -1 則表示存在環
	};

	int len = getMaxLenInGraph(Adj);
	printf("the length of graphic is : %d\n", len);

	system("pause");
	return 0;
}



2.求解能連線成的最長字串( 首先建圖,然後利用上面提供的函式即可求解 )

程式碼實現如下:

#include <iostream>
#include <string>

using namespace std;

#define VERTEX_NUM	8
#define NOT_VISITED	-1	//該頂點未被訪問
#define VISITED		0	//該頂點已經被訪問,但它的鄰接點未被訪問完成
#define FINISHED	1	//結束訪問該頂點的鄰接表
#define IS_CIRCLE	-1

int maxLen = -1;
int getMaxLenInGraph(int adj[][VERTEX_NUM]); //返回-1表示該有向圖中存在環路
int DFS_VISTI(int state[], int adj[][VERTEX_NUM], int i, int *len); //深度優先遍歷	
void build_graph(string str[], int graph[][VERTEX_NUM]);

int main()
{
	string str[] = {
		"abc", "bcf", "cfg", "fga", 
		"gam", "bcg", "cga", "gai",
	};
	//其鄰接表,若改變4節點為"gab",則出現迴圈
	//0-1-5
	//1-2
	//2-3
	//3-4-7
	//4
	//5-6
	//6-4-7
	//7

	int Graph[VERTEX_NUM][VERTEX_NUM];

	//構造圖的鄰接表
	build_graph(str, Graph);

	int len = getMaxLenInGraph(Graph);
	printf("該有向圖最長路徑為(-1表示存在環): %d\n", len);
	if (len != -1)
		printf("可以連線成的最長字串為:%d\n", str[0].length()+len);

	system("pause");
	return 0;
}

void build_graph(string str[], int gra[][VERTEX_NUM])
{
	for (int i = 0; i < VERTEX_NUM; i++)
		for (int j = 0; j < VERTEX_NUM; j++)
		{
			if (j == 0)
				gra[i][j] = i;
			else
				gra[i][j] = -1;
		}

	int index;
	for (int i = 0 ; i < VERTEX_NUM; i++)
	{
		index = 1;
		string suffix = str[i].substr(1);
		for (int j = 0; j < VERTEX_NUM; j++)
		{
			if (str[j].find(suffix) == 0)
				gra[i][index++] = j;
		}
	}
}

出現問題在所難免,如有發現錯誤的朋友,請指正!

注:執行時會提示棧溢位的問題,修改property->configuration properties -> linker -> system中的stack reserve size和 stack commit size即可~

相關推薦

路徑是否存在環路結構

問題描述: 有n個長為m+1的字串,如果某個字串的最後m個字元與某個字串的前m個字元匹配,則兩個字串可以連線。問這n個字串最多可以連成一個多長的字串,如果出現迴圈,則返回錯誤。 分析: 把每個字串看成一個圖的頂點,兩個字串可以連線就形成一條有向邊。相當於判斷一個有向圖是否存

Til the Cows Come Home (路徑問題)

One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the big cow party to be held at far

拓撲排序+路徑(無環加權路徑演算法)

特點:        1、線性時間內解決單點最短路徑問題        2、能夠處理負權邊問題        3、能夠找出最長路徑 不足:因為是基於拓撲排序的,所以不能解決帶環的問題  import java.util.ArrayList; import java.util

路徑條數

(2)Dijkstra演算法 使用兩次Dij演算法,第一次計算最短路徑,第二次計算路徑條數。 int cost[MAX][MAX],dist[MAX],dist2[MAX],num[MAX][MAX]={{0,0}},ci[MAX]={0}; //dist2[]是在第二次寫dijikstra時,記錄最短路

論-BFS解無權路徑距離

概述 本篇部落格主要內容: 對廣度優先搜尋演算法(Breadth-First-Search)進行介紹; 介紹用鄰接表的儲存結構實現一個圖(附C++實現原始碼); 介紹用BFS演算法求解無權有向圖(附C++實現原始碼)。 廣度優先搜尋演算法(Breadt

2017 icpc南寧 The Maximum Unreachable Node Set(反鏈)

In this problem, we would like to talk about unreachable sets of a directed acyclic graph G=(V,E)G = (V,E)G=(V,E). In mathematics a direct

洛谷 - P1434 - 滑雪 -

col pri main urn 滑雪 return def scan pos https://www.luogu.org/problemnew/show/P1434 有向圖的最長鏈怎麽求?有環肯定不行,這裏保證無環。(否則應該使用toposort先求出所有不帶環的位置)

The Largest Clique UVA - 11324 (大團)

while esp sta pan n) ace break ems using The Largest Clique UVA - 11324 題意:有向圖最大團。求任意兩點可達(不是互達)的最多點數。 先求出SCC,然後縮點,新圖就變成了一個DAG,每個點的權值為內點

zoj 3471 Most Powerful ()大生成樹 狀壓dp

最大值 href != 氣體 state span 生成 long logs 題目鏈接 題意 \(N\)種氣體,\(i\)氣體與\(j\)氣體碰撞會: 產生\(a[i][j]\)的威力; 導致\(j\)氣體消失。 求產生威力之和的最大值。 思路 和前幾題找圖上路徑的題不

vijos1423最佳路線——小環模板

題目:vijos1423. 題目大意:給定一些單向直道與彎道,並且給出每條單向直道連線哪兩條彎道,讓你求出經過彎道1的邊權最小的環. 這道題我們可以將彎道看成點,將直道看成有向邊,那麼原問題其實就是求經過點1的最小環. 解決最小環問題一般用的是floyd演算法或dijkstra演算法

18.11.16 POJ 1860 Currency Exchange(短路)

描述 Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and performs exchange

How Many Maos Does the Guanxi Worth(無路徑大值)

Guanxi" is a very important word in Chinese. It kind of means "relationship" or "contact". Guanxi can be based on friendship, but also can be built on

六度分離 (無路徑問題)

1967年,美國著名的社會學家斯坦利·米爾格蘭姆提出了一個名為“小世界現象(small world phenomenon)”的著名假說,大意是說,任何2個素不相識的人中間最多隻隔著6個人,即只用6個人就可以將他們聯絡在一起,因此他的理論也被稱為“六度分離”理論(six degrees of sepa

路徑問題

  給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。 Input 輸入n,m,點的編號是1~n,然後是m行,每行4個數 a,b,d,p,表示a和b之間有一條邊,且其長度為d,花費

小環

floyd求。 for(int k=1;k<=n;k++) {  for(int i=1;i<k;i++)   for(int j=1;j<k;j++)    ans=min(ans,dis[i][k]+dis[k][j]+map1[j][i])  for

迪傑斯特拉(Dijkstra)演算法--網路路徑

單源最短路徑問題是:對於給定的有向網路G=(V,E)及單個源點v,求v到G的其餘各頂點的最短路徑。 演算法的基本思想 a.初始時,S只包含源點,即S={v},v的距離為0。U包含除v外的其他頂點,即:U={其餘頂點},若v與U中頂點u有邊,則<u,v>

12.3日+佛洛依德處理無小環+dijkstra處理小環

  昨天的資料庫考試,題目本身都簡單的,但是感覺時間有點緊張,可能和自己有點墨跡有關。題目不怕不會做,就怕讀錯題,上了大學養成了考試“做完一遍要檢查的壞習慣”,這次沒時間檢查,所以有種做的不好的感覺。       弗洛伊德演算法是運用的動態規劃的思

短路Dijkstras演算法過程動態演示

/********************************************** 2015.1.9---1.12 by yzk ************************************************************

Vijos - 最佳路線(Floyd+小環)

https://vijos.org/p/1423 題目描述 年久失修的賽道令國際汽聯十分不滿。汽聯命令主辦方立即對賽道進行調整,否則將取消其主辦權。主辦方當然必須馬上開始行動。 賽道測評人員經過了三天三夜的資料採集,選出了若干可以使用的道路和各道路行駛所需的時間。這些道路包括若干直道

[Vijos 2024]無路徑短路)

https://vijos.org/p/2024 題意: 給你圖中每兩個點的最短路,問你可不可以增加一條邊的權值,使最小值不受影響,讓這個最大值最大。 思路:一個圖已經給定了,怎樣才能增加一個邊的權值使他最小值不受影響呢,應該可以想到就是當一個點可以被鬆弛的時候 我們可以