1. 程式人生 > >博客作業06--圖

博客作業06--圖

情況 分享 http 問題 main 二分 入隊 結點 cstring

1.學習總結

1.1圖的思維導圖

1.2 圖結構學習體會

  • 深度遍歷算法、廣度遍歷算法都是遍歷圖的算法。深度優先遍歷的策略就是首先訪問第一個鄰接結點,然後再以這個被訪問的鄰接結點作為初始結點,訪問它的第一個鄰接結點;廣度遍歷類似於一個分層搜索的過程,廣度優先遍歷需要使用一個隊列以保持訪問過的結點的順序,以便按這個順序來訪問這些結點的鄰接結點。Prim和Kruscal算法都是生成最小生成樹的算法。從策略上來說,Prim算法是直接查找,多次尋找鄰邊的權重最小值,而Kruskal是需要先對權重排序後查找的;Kruskal在算法效率上是比Prim快的,因為Kruskal只需一次對權重的排序就能找到最小生成樹,而Prim算法需要多次對鄰邊排序才能找到。Dijkstra算法是解決最短路徑問題,Dijkstra算法使用了廣度優先搜索解決賦權有向圖或者無向圖的單源最短路徑問題,算法最終得到一個最短路徑樹;Dijkstra算法采用的是一種貪心的策略,聲明一個數組dis來保存源點到各個頂點的最短距離和一個保存已經找到了最短路徑的頂點的集合。拓撲排序算法,是將一個有向無環圖G的所有的頂點排成一個線性序列,使得有向圖中的任意的頂點u 和 v 構成的弧

2.PTA實驗作業

題目1:7-1 圖著色問題

1.設計思路

main函數
輸入v,e,k
建圖CreateAdj( G,v,e )
輸入n
while(n--)
    set <int> E
    flag=true
    for i=1 to i<=v
    輸入color[i],並且E.insert(color[i]),visit[i] = 0。
end
定義一個l=E.size()
若輸入的顏色種類不等於k
    cout<<No,continue。
do{
    for(  i=1, i<=v&&flag ; i++ )
      若visit[i]==0
{ 則調用Check( G,k,i ); break;} }while( flag && i<=v ); 若 flag ==1,則cout << "Yes" 否則 cout << "No" Check函數 建立一個指針指向頂點v,令visit[v]=1,表示已經遍歷過了。 while(p) 若color[p->adjvex]==color[v],則說明頂點相鄰的點顏色相同 flag=false。 若!visit[p->adjvex],則遞歸搜索。 p=p->nextarc end

2.代碼截圖

技術分享圖片
技術分享圖片

3.PTA提交列表說明

技術分享圖片

  • 剛開始只用了一次循環來判斷著色,可能會漏掉一些頂點,導致圖不連通。後來,在外面又嵌套了一層循環就解決了。

題目2:7-3 六度空間

1.設計思路

建立一個隊列queue <int> q,用來解決層數問題。
遍歷過的x,令visit[x]=1,並將x入隊q
定義lengh=1來表示層數,last=x保存每一層最後一個頂點,count=1計數人數。
while(!q.empty())
    定義v=q.front(),定義一個指針p指向v
    遍歷該層所有頂點,若該點未遍歷則count++,若lengh<6層,則將該點入隊。
    若last==v,則lengh++,並且last=q.back()
end
輸出x,100.0*count/G->n。

2.代碼截圖

技術分享圖片

3.PTA提交列表說明

技術分享圖片

  • 本題一開始不大理解六度是什麽意思,後來再查找相關題目理解意思後就明白了。

題目3:7-5 暢通工程之最低成本建設問題

1.設計思路

這題的基本思路就是利用prim算法構建最小生成樹。

2.代碼截圖

技術分享圖片

3.PTA提交列表說明

技術分享圖片

  • 沒有問題

3.截圖本周題目集的PTA最後排名

3.1 PTA排名

技術分享圖片

3.2 我的得分:2.5

4. 閱讀代碼

匈牙利算法

#include<cstdio>  
#include<cstring>  
using namespace std;  
  
int n,m,ans;  
int match[210];//母牛i的配偶是公牛match[i]  
bool chw[210];//在此趟詢問中,母牛i是否被詢問過  
bool mp[210][210];//公牛i與母牛j是否有關系  
  
bool find_ans(int x)  
{  
    for(int i=1;i<=m;i++)  
    {  
        if(mp[x][i]==true&&chw[i]==true)  
        {  
            chw[i]=false;  
            if(match[i]==0||find_ans(match[i])==true)  
            //母牛沒有配偶||匹配該母牛的公牛能否換一頭母牛匹配   
            {  
                match[i]=x;  
                return true;  
            }  
        }  
    }  
    return false;  
}  
  
int main()  
{  
    while(scanf("%d %d",&n,&m)!=EOF)  
    {  
        memset(mp,false,sizeof(mp));  
        for(int i=1;i<=n;i++)  
        {  
            int k,x;  
            scanf("%d",&k);  
            for(int j=1;j<=k;j++)  
            {  
                scanf("%d",&x);  
                mp[i][x]=true;  
            }  
        }  
        ans=0;  
        memset(match,0,sizeof(match));  
        for(int i=1;i<=n;i++)  
        {  
            memset(chw,true,sizeof(chw));  
            if(find_ans(i)==true) ans++;  
        }  
        printf("%d\n",ans);  
    }  
    return 0;  
}  
  • 公牛是二分圖的一個集合,母牛也是。接著公牛逐一詢問母牛,會出現兩種情況。1、如果母牛未被匹配,公牛匹配它;2、如果母牛已被匹配,詢問母牛的原配公牛能否換另一頭母牛匹配。若行,則該公牛可以獲得此母牛;反之,該公牛無法得到該母牛。如果該失配公牛問遍了所有母牛,仍然不能找到合適的配偶,則該公牛匹配失敗(ans不能+1)。匈牙利算法是眾多用於解決線性任務分配問題的算法之一,是用來解決二分圖最大匹配問題的經典算法,可以在多項式時間內解決問題。

5. 代碼Git提交記錄截圖

技術分享圖片

博客作業06--圖