//
求解关键路径
//
效率极低
最好使用
矩阵
或者十字链表
//
若采用十字链表和矩阵可以大幅度的提高效率
#include
"stdafx.h"
#include
<iostream>
#include
<vector>
#include
<list>
#include
<algorithm>
enum
{
Vertex_No_Connection
= -1,
Vertex_Total_Number
= 9,
Vertex_Max_Edge_Value
= 10000,
};
//
连接头结点的后面
next
结点
struct
SNextHeadNode
{
int
nVertexNode
;
int
nEdgeValue
;
SNextHeadNode
*
pNextNode
;
};
//
头结点
struct
SHeadNode
{
int
nVertexNode
;
SNextHeadNode
*
pFirstLink
;
};
SHeadNode
*
headNodeSet
[
Vertex_Total_Number
];
int
InDgreeOfNodeSet
[
Vertex_Total_Number
];
int
nPreOrderTag
[
Vertex_Total_Number
];
//
前向遍历产生的
Tag
标识
int
nPostOrderTag
[
Vertex_Total_Number
];
//
后向遍历产生的
Tag
标识
int
nSourceIndex
;
//
源点
int
nMaxNodeIndex
;
//
汇点
void
InitHeadList
()
{
int
nThreeItemNum
[11][3] =
{
{ 0, 1, 6 }, { 0, 2, 4 }, { 0, 3, 5 }, { 1, 4, 1 },
{ 2, 4, 1 }, { 4, 6, 9 }, { 4, 7, 7 }, { 6, 8, 2 },
{ 7, 8, 4 }, { 3, 5, 2 }, { 5, 7, 4 }
};
for
(
int
i
= 0;
i
<
Vertex_Total_Number
; ++
i
)
{
headNodeSet
[
i
] =
new
SHeadNode
;
if
( !
headNodeSet
[
i
] )
{
std
::
cout
<<
"Error 1"
<<
std
::
endl
;
system
(
"pause"
);
return
;
}
headNodeSet
[
i
]->
nVertexNode
=
i
;
headNodeSet
[
i
]->
pFirstLink
=
NULL
;
}
for
(
int
i
= 0;
i
< 11; ++
i
)
{
SNextHeadNode
*
pNextHeadNode
=
new
SNextHeadNode
;
if
( !
pNextHeadNode
)
{
std
::
cout
<<
"Error 2"
<<
std
::
endl
;
system
(
"pause"
);
return
;
}
pNextHeadNode
->
pNextNode
=
NULL
;
pNextHeadNode
->
nVertexNode
=
nThreeItemNum
[
i
][1];
pNextHeadNode
->
nEdgeValue
=
nThreeItemNum
[
i
][2];
// Front Insert
int
nSourceIndex
=
nThreeItemNum
[
i
][0];
pNextHeadNode
->
pNextNode
=
headNodeSet
[
nSourceIndex
]->
pFirstLink
;
headNodeSet
[
nSourceIndex
]->
pFirstLink
=
pNextHeadNode
;
}
}
void
InitInDgreeOfNodeSet
()
{
for
(
int
i
= 0;
i
<
Vertex_Total_Number
; ++
i
)
{
InDgreeOfNodeSet
[
i
] = 0;
}
for
(
int
i
= 0;
i
<
Vertex_Total_Number
; ++
i
)
{
SNextHeadNode
*
pLinkHeadNode
=
headNodeSet
[
i
]->
pFirstLink
;
while
(
pLinkHeadNode
)
{
int
nLinkNode
=
pLinkHeadNode
->
nVertexNode
;
++
InDgreeOfNodeSet
[
nLinkNode
];
pLinkHeadNode
=
pLinkHeadNode
->
pNextNode
;
}
}
}
void
InitPreOrderTag
()
{
// nPreOrderTag
for
(
int
i
= 0;
i
<
Vertex_Total_Number
; ++
i
)
nPreOrderTag
[
i
] = 0;
}
void
FindTheSourceIndex
()
{
for
(
int
i
= 0;
i
<
Vertex_Total_Number
; ++
i
)
{
if
(
InDgreeOfNodeSet
[
i
] == 0 )
{
nSourceIndex
=
i
;
break
;
}
}
}
void
SolutionPostNode
(
int
nMaxValue
,
int
nMaxIndex
)
{
if
(
nMaxIndex
==
nSourceIndex
)
return
;
for
(
int
i
= 0;
i
<
Vertex_Total_Number
; ++
i
)
{
int
nSourceNodeIndex
=
headNodeSet
[
i
]->
nVertexNode
;
SNextHeadNode
*
pLinkNode
=
headNodeSet
[
i
]->
pFirstLink
;
while
(
pLinkNode
)
{
int
nDestNodeIndex
=
pLinkNode
->
nVertexNode
;
if
(
nDestNodeIndex
==
nMaxIndex
)
{
int
nEdgeValue
=
pLinkNode
->
nEdgeValue
;
if
(
nMaxValue
-
nEdgeValue
<
nPostOrderTag
[
nDestNodeIndex
] )
{
nPostOrderTag
[
nSourceNodeIndex
] =
nMaxValue
-
nEdgeValue
;
SolutionPostNode
(
nPostOrderTag
[
nSourceNodeIndex
],
nSourceNodeIndex
);
}
}
pLinkNode
=
pLinkNode
->
pNextNode
;
}
}
}
void
Process
()
{
FindTheSourceIndex
();
//
寻找入度为的结点找到最长路径,即最短时间
while
( 1 )
{
int
nIndex
= -1;
for
(
int
i
= 0;
i
<
Vertex_Total_Number
; ++
i
)
{
if
(
InDgreeOfNodeSet
[
i
] == 0 )
{
nIndex
=
i
;
break
;
}
}
if
(
nIndex
== -1 )
break
;
//
找到度数为点将其入度置为
-1
InDgreeOfNodeSet
[
nIndex
] = -1;
SNextHeadNode
*
pLinkNextNode
=
headNodeSet
[
nIndex
]->
pFirstLink
;
while
(
pLinkNextNode
)
{
int
nNodeIndex
=
pLinkNextNode
->
nVertexNode
;
int
nEdgeValue
=
pLinkNextNode
->
nEdgeValue
;
--
InDgreeOfNodeSet
[
nNodeIndex
];
if
(
nPreOrderTag
[
nIndex
] +
nEdgeValue
>
nPreOrderTag
[
nNodeIndex
] )
nPreOrderTag
[
nNodeIndex
] =
nPreOrderTag
[
nIndex
] +
nEdgeValue
;
pLinkNextNode
=
pLinkNextNode
->
pNextNode
;
}
}
//
求解
nPost
后向结点的值
int
nMaxValue
= -1;
for
(
int
i
= 0;
i
<
Vertex_Total_Number
; ++
i
)
{
if
(
nPreOrderTag
[
i
] >
nMaxValue
)
{
nMaxValue
=
nPreOrderTag
[
i
];
nMaxNodeIndex
=
i
;
}
}
for
(
int
i
= 0;
i
<
Vertex_Total_Number
; ++
i
)
{
nPostOrderTag
[
i
] =
nMaxValue
;
}
SolutionPostNode
(
nMaxValue
,
nMaxNodeIndex
);
nPostOrderTag
[
nSourceIndex
] = 0;
}
void
PrintHelp
(
int
nSource
)
{
if
(
nSource
==
nMaxNodeIndex
)
{
std
::
cout
<<
nSource
<<
std
::
endl
;
return
;
}
std
::
cout
<<
nSource
<<
"---->"
;
SNextHeadNode
*
pLinkNextHead
=
headNodeSet
[
nSource
]->
pFirstLink
;
while
(
pLinkNextHead
)
{
int
nVertexIndex
=
pLinkNextHead
->
nVertexNode
;
if
(
nPostOrderTag
[
nVertexIndex
] ==
nPreOrderTag
[
nVertexIndex
] )
{
PrintHelp
(
nVertexIndex
);
}
pLinkNextHead
=
pLinkNextHead
->
pNextNode
;
}
}
void
PrintPathInfo
()
{
//
广度搜索。。。输出所有的最优解
PrintHelp
(
nSourceIndex
);
}
int
_tmain
(
int
argc
,
_TCHAR
*
argv
[])
{
InitHeadList
();
InitInDgreeOfNodeSet
();
InitPreOrderTag
();
Process
();
PrintPathInfo
();
system
(
"pause"
);
return
0;
}