1、最小生成樹(最小代價生成樹)
Prim法:(加點法)
時間複雜度:O(n*n)——適用於稠密圖
輔助數組:lowcost(=arc[0][i])和adjvex(=0)(0是始點)
void prime(MGraph G){
for(int i=1;i<G.vertexNu;i++){//若有n個點,需要執行共n-1次操作
lowcost[i]=G.arc[0][i]; //用於從中選取最短邊
adjvex[i]=0;
}
lowcost[0]=0;
for(i=1;i<G.vertexNum;i+++){
k=MinEdge(lowcost,G.vertexNum)
cout<<K<<adjvex[k]<<lowcost[k];
lowcost[k]=0;
for(j=1;j<G.vertexNum;j++)
if((G.arc[k][j]<lowcost[j]){
lowcost[j]=G.arc[k][j];
arcvex[j]=k;
}
}
}
Kruskal法:(加邊法)
時間複雜度:O(eloge)
int main(){
int arcNum, int vertexNum;
EdgeNode *edge;
int *parent;
cout<<"please input the number of vertexNum:"; cin>>vertexNum;
cout<<"please input the number of edges:"; cin>>arcNum;
edge=new EdgeNode[arcNum]; parent=new int[vertexNum];
for(int i=0;i<arcNum;i++) {
cout<<"Please input the edges:";
cin>>edge[i].from>>edge[i].to>>edge[i].weight;
}
sort(edges, G); //對邊集數組進行堆排序,時間複雜性爲O(eloge)
for (i=0;i<vertexNum;i++)
parent[i]=-1; //每個節點分屬於不同的集合
int k=0,begin,end,count=0;
cout<<"next is the MST :"<<endl;
for (k=0;k<arcNum;k++) {
begin=edge[k].from; end=edge[k].to;
int m,n;
m=Find(parent,begin); n=Find(parent,end);
if(m!=n) {
cout<<begin<<","<<end<<","<<edge[k].weight<<endl;
parent[n]=m;
count++;
if(count==vertexNum-1) break;} }
return 0;}
2、最短路徑
Dijkstra方法(時間複雜度O(n*n))
const int MAX=1000;
void Dijkstra(MGraph g, int v){
for ( i =0; i<g.vexnum ; i++){
dist[i]=g.arcs[v][i];
if ( dist[i]!= MAX)
path [i]=g.vertex[v]+g.vertex[i];
else
path[i]=“”;
}
S[0]=g.vertex[v];
num=1;
While (num<g.vextexNum){
k=0;
for(i=0;i<G.vertexNum;i++)
if((dist[i]<dist[k]) k=i
cout<<dist[k]<<path[k];
s[num++]=G.vertex[k];
for(i=0;i<G.vertexNum;i++)
if(dist[k]+g.arc[k][i]<dist[i] {
dist[i]=dist[k]+g.arc[k][i];
path[i]=path[k]+g.vertex[i];
}}}
Floyed方法(時間複雜度O(n*n*n))
void Floyd(MGraph G)
{
for (i=0; i<G.vertexNum; i++)
for (j=0; j<G.vertexNum; j++)
{
dist[i][j]=G.arc[i][j];
if (dist[i][j]!=∞)
path[i][j]=G.vertex[i]+G.vertex[j];
else path[i][j]="";
}
for (k=0; k<G.vertexNum; k++)
for (i=0; i<G.vertexNum; i++)
for (j=0; j<G.vertexNum; j++)
if (dist[i][k]+dist[k][j]<dist[i][j]) {
dist[i][j]=dist[i][k]+dist[k][j];
path[i][j]=path[i][k]+path[k][j]; }}
3、AOV網
特點:
- AOV網中的弧表示活動之間存在的某種制約關係
- AOV網中不能出現迴路
PS:拓撲序列使得AOV網中所有應存在的前驅和後繼關係都能得到滿足。
拓撲排序:
- 從AOV網中選擇一個沒有前驅的頂點並且輸出;
- 從AOV網中刪去該頂點,並且刪去所有以該頂點爲尾的弧;
- 重複上述兩步,直到全部頂點都被輸出,或AOV網中不存在沒有前驅的頂點。
void TOpSort(){
int top=-1, count=0;
for(int i=0;i<vertexnum;i++)
if(adjlist[i].in==0) s[++top]=i;
while(top!=-1){
j=s[top--]; cout <<adjlist[j].vertext; count++;
p=adjlist[j].firstedge;
while(p!=NULL){
k=p->adjvex; adjlist[k].in--;
if(adjlist[k].in==0) s[top++]=k;
p=p->next;
}
}
If (count<vertexNum) cout<<“有迴路”;}
4、AOE網
性質:
- 只有在某頂點所代表的事件發生後,從該頂點出發的各活動才能開始;
- 只有在進入某頂點的各活動都結束,該頂點所代表的事件才能發生。
關鍵路徑:
- 事件的最早發生時間ve[k]
- 事件的最遲發生時間vl[k]
- 活動的最早開始時間e[i]
- 活動的最晚開始時間l[i]
ve[k]的計算
q.push(0);//源點事件入隊
for(j=0;j<vertexnum;j++) { //初始化每個事件最早發生時間
ve[j]=0; visit[j]=0; }
visit[0]=1;
while(!q.empty()) {
i=q.front(); //利用標準模板庫中的隊列實現
q.pop();
for(j=0;j<vertexnum;j++){//計算i的鄰接點的ve
if(adjlist[i][j]!=9999 && ve[i]+adjlist[i][j]>ve[j] ){
ve[j]=ve[i]+adjlist[i][j];
if(!visit[j]) //如果j沒有被訪問過,頂點j入隊
q.push(j);
visit[j]=1;
}
}
}
vl[k]的計算
q.push(vertexnum-1);
for(j=0;j<vertexnum;j++) {
vl[j]=ve[vertexnum-1]; visit[j]=0; }
while(!q.empty()) {
i=q.front();
q.pop();
for(j=0;j<vertexnum;j++) {
if(adjlist[j][i]!=9999 && vl[i]-adjlist[j][i]<vl[j] ){
vl[j]=vl[i]-adjlist[j][i];
if(!visit[j])
q.push(j);
visit[j]=1;
}
}
}
活動最早開始時間e[i]
for(i=0;i<e;i++)
{
edge[i].e=ve[edge[i].from];
}
活動最晚開始時間l[i]
for(i=0;i<e;i++)
{
edge[i].e=ve[edge[i].from];
edge[i].l=vl[edge[i].to]-adjlist[edge[i].from][edge[i].to];
if(edge[i].e==edge[i].l)
cout<<edge[i].from<<" "<<edge[i].to<<endl;
}