日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

贪心算法的几个应用

發布時間:2023/12/10 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 贪心算法的几个应用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
貪心算法具有2個性質:

1、貪心選擇性質:只在當前狀態下做最優選擇,即局部最優選擇,再自頂向下,去解做出這個選擇后產生的相應子問題。每做一次選擇,問題就轉化為規模更小的子問題。對于一個具體問題,要確定它是否具有貪心選擇性質,必須證明每一步做出的選擇最終導致問題的整體最優解。

2、最優子結構性質:問題的最優解包含子問題的最優解。

?

貪心算法的幾個應用:

哈夫曼編碼:二叉樹&最小優先級隊列

dijktra:原始集合、選中節點集合、dist

最小生成樹:prim:原始集合、選中幾點集合、closestlowcost

最小生成樹:kruskul:并查集&最小優先級隊列

?

具體代碼:?

dijktra:

設鄰接矩陣:a[][],有n個節點。

1.初始化:dist[i] = a[v][i],原始集合中只有v

2.dist的最小值,加入原始集合中,更新其他dist,更新n-1

具體代碼如下:

/*

5

0 10 10000 30 100

10000 0 50 10000 10000

10000 10000 0 10000 10

10000 10000 20 0 60

10000 10000 10000 10000 0

?

1

*/

?

#include<stdio.h>

#include<stdlib.h>

?

#define NUM 10

#define MAX_VALUE 10000

?

int dist[NUM];

int s[NUM];

int pre[NUM];

?

void? dijkstra(int v,int a[NUM][NUM], int n){

????? //初始化

????? int i=1,j=1;

????? for(i=1; i<=n; i++){

?????????? dist[i] = a[v][i];

?????????? s[i] = false;

?????????? if(a[v][i] == MAX_VALUE){

???????????????? pre[i] = 0;

?????????? }else{

???????????????? pre[i] = v;

?????????? }

????? }????

?????

????? s[v] = true;

????? dist[v] = 0;

?????

????? //更新n-1次

????? int min = 0,tmp=v;

????? for(i=1; i<n; i++){

??????????? //找最小的dist

??????????? min = MAX_VALUE;

??????????? for(j=1; j<=n; j++){

???????????????????? if(!s[j] && min>dist[j]){

????????????????????????????? min = dist[j];

????????????????????????????? tmp = j;

???????????????????? }

??????????? }

??????????? s[tmp] = true;?? //tmp的初始值是v,不能為0或者隨意

?????

??????????? //用最小的dist更新已有的dist

??????????? for(j=1; j<=n; j++){

???????????????????? if(!s[j] && a[tmp][j] < MAX_VALUE && (dist[tmp]+a[tmp][j] < dist[j])){

????????????????????????????? dist[j] = dist[tmp]+a[tmp][j];

????????????????????????????? pre[j] = tmp;

???????????????????? }

??????????? }

????? }

}

?

int main(){

??? int i=1,j=1,v,n,a[NUM][NUM];

???

??? //輸入鄰接矩陣

??? scanf("%d",&n);

??? for(i=1; i<=n; i++){

?????? for(j=1; j<=n; j++){

?????????? scanf("%d",&a[i][j]);

?????? }

??? }

???

??? //輸入起始節點

??? scanf("%d",&v);

???

??? //計算dijkstra

??? dijkstra(v,a,n);

???

??? //打印源點到各點的最短距離

??? int tmp = 0;

??? for(i=1; i<=n; i++){

?????????? printf("從%d到%d的距離是%d\n",v,i,dist[i]);

?????????? tmp = i;

?????????? printf("從%d到%d的最短路經過:");

?????????? while(pre[tmp]>0 && pre[tmp] != v){

?????????????? printf("%d ",pre[tmp]);

?????????????? tmp = pre[tmp];

?????????? }

?????????? printf("%d\n",v);

??? }

?

??? system("pause");

??? return 0;

}

?

時間復雜度分析:使用鄰接矩陣,o(n*n)

?

最小生成樹:prim

/*
6
0 6 1 5 10000 10000
6 0 5 10000 3 10000
1 5 0 5 6 1
5 10000 5 0 10000 2
10000 3 6 10000 0 6
10000 10000 1 2 6 0

*/

#include<stdio.h>
#include<stdlib.h>

#define NUM 10
#define MAX_VALUE 10000
?
int closest[NUM];? //closest[j]記錄j和S中的鄰接節點中距離最近的節點?
int lowcost[NUM];? //lowcost[j]記錄j和S中最近鄰接點的距離?
int s[NUM];??????? //s[j] = true,標記j在S中

int prim(int a[NUM][NUM],int n){
??? //初始化
??? int i,j,sum=0;
??? for(i=1; i<=n; i++){
???????????? closest[i] = 1;
???????????? lowcost[i] = a[i][1];
???????????? s[i] = false;
??? }
??? s[1] = true;

??? for(j=1; j<n; j++){
??????? //尋找離S中節點最近的節點及距離
??????? int min = MAX_VALUE,v=1;
??????? for(i=1; i<=n; i++){
???????????? if(!s[i] && min > lowcost[i]){
????????????????????? min = lowcost[i];
????????????????????? v = i;
???????????? }
??????? }
??????? s[v] = true;
??????? sum += lowcost[v];
????
??????? //每添加一個新的節點到S,比較節點i和S中以前節點的最短距離 和 i和新增節點的最短距離,更新closest和c
??????? for(i=1; i<=n; i++){
???????????? if(!s[i] && a[i][v] < lowcost[i]){
????????????????????? lowcost[i] = a[i][v];
???????????? }
??????? }????????????
??? }?????
????
??? return sum;???????????????????
????
}

int main(){
??? int i=1,j=1,n,a[NUM][NUM];
????
??? //輸入鄰接矩陣?
??? scanf("%d",&n);
??? for(i=1; i<=n; i++){
?????? for(j=1; j<=n; j++){
?????????? scanf("%d",&a[i][j]);
?????? }
??? }
????
??? printf("%d",prim(a,n));
????
??? system("pause");
??? return 0;
}?

時間復雜度是:o(n*n)

說明:最小生成樹primdijkstra相似,dijkstra保存了各點和源點的最近距離(dist)prim保存了各點和S中節點的最近鄰接點及和最近鄰接點的距離(closest, lowcost)。程序的書寫過程相似,先初始化,再找最小的距離,再更新數組。

總結

以上是生活随笔為你收集整理的贪心算法的几个应用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。