c++实现图的单源最短路径
图的单源最短路径就是指,指定有向图的一个顶点,然后求得该顶点到达其它顶点的最短路;
算法描述:
void Dijkstra(C)
/*对给定的有向图,求从原点1到其余每个顶点的最短路径长*/
{
S ={1};/*1为源点*/
for(i =2 ;i <= n;i++)
{
D[i] = C[i][j];
}
for(i =1; i<=n-1;i++)
{
从V-S中选择一个w(顶点),使得D[w]的值最小;
把w加入S;
for(V-S中的每一个顶点v)
{
D[v] = min(D[v],D[w] +C[w][r]);
}
}
}
算法还是比较简单的;接下来实现:
1 #include <iostream>
2 using namespace std;
3
4 //定义集合类:
5 class S
6 {
7 int* s;
8 int num;
9 int now;
10 public:
11 //初始化集合:
12 S(int n){
13 num = n;
14 s = new int[num];
15 now = 0;
16 }
17 //添加元素到集合:
18 int addElementype(int a)
19 {
20 if(now < num)
21 {
22 if(isExist(a) == 0)
23 {
24 s[now] = a;
25 now++;
26 return 0;
27 }
28 else
29 return -1;
30 }
31 else
32 return 1;
33
34 }
35 //判断元素是否在集合中:
36 int isExist(int temp)
37 {
38 int flag =0;
39 for(int i =0 ;i<now;i++)
40 {
41 if(s[i]==temp)
42 flag =1;
43 }
44 return flag;
45 }
46 //返回一个不再集合中的元素:
47 int noExit()
48 {
49 for(int i = 0;i<num;i++)
50 if (!isExist(i))
51 return i;
52 }
53 };
54
55 //找到路径中不再集合muser的最小的:
56 int findMin(int* a,int num,S muser);
57 //返回a,b之间小的一个:
58 int Min(int a,int b);
59 //在邻接矩阵中寻找源choose的所有最短路,并输出:
60 void MinWay(int** C,S muser,int choose,int number);
61
62 int main()
63 {
64 //矩阵宽度number:
65 FILE* fin;
66 fin = fopen("in.txt","rb");
67 int number;
68 int temp;
69 fscanf(fin,"%d",&number);
70
71 S muster(number);
72 ////文件出入矩阵:
73 int** C = new int*[number];
74 for(int i = 0;i < number; i++)
75 {
76 C[i] = new int[number];
77 }
78 for(int i =0 ;i<number;i++)
79 {
80 for(int j = 0;j<number;j++)
81 {
82 fscanf(fin,"%d",&temp);
83 C[i][j] = temp;
84 }
85 }
86
87 //输入源:
88 int choose = 0;
89 cout<<"Please input source point!&&input \"-1\" to exit!"<<endl;
90 while (scanf("%d",&choose)&&choose!=-1)
91 {
92 choose -= 1;
93 if(choose<0||choose>number-1)
94 {
95 cout<<"No that point!"<<endl;
96 }else
97 {
98 MinWay(C,muster,choose,number);
99 }
100 }
101 getchar();
102 return 0;
103 }
104
105
106 void MinWay(int** C,S muster,int choose,int number)
107 {
108 //以矩阵第一行,初始化源的所有最短路径:
109 int* D = new int[number];
110 for (int i =0 ;i<number; i++)
111 {
112 D[i] = C[choose][i];
113 }
114 //将源加入集合:
115 muster.addElementype(choose);
116
117
118 int w;
119 for(int i=1;i<number;i++)
120 {
121 //找到未加入到集合中的,路径中最小的w:
122 w = findMin(D,number,muster);
123 //将w加入集合muster:
124 muster.addElementype(w);
125 //遍历所有节点,判断是之前的路径短,还是从w经过比较短:
126 for(int v=0 ;v< number ;v++)
127 {
128 D[v] = Min(D[v],D[w]+C[w][v]);
129 }
130
131 }
132 //输出:
133 for(int i =0 ;i<number;i++)
134 {
135 printf("%d ",D[i]);
136 }
137 cout<<endl;
138 }
139
140 int findMin(int* a,int num,S muser)
141 {
142 //生成一个不再集合中的元素为temp初始化:
143 int temp = muser.noExit();
144 for(int i = 0;i<num ;i++)
145 {
146 //取最小值,确保不再集合中:
147 if(!muser.isExist(i))
148 if( a[temp] > a[i] )
149 {
150 temp = i;
151 }
152 }
153 return temp;
154 }
155
156 int Min(int a,int b)
157 {
158 if(a>b)
159 return b;
160 else
161 return a;
162 }
程序很简单,一个小时就可以写出来;只要是算法思想没见过,就贴出来了。