1. 程式人生 > 實用技巧 >[天梯賽] L2-023 圖著色問題 思路以及一些坑

[天梯賽] L2-023 圖著色問題 思路以及一些坑

這題本身是個水題,但因為自己粗心沒看清題意導致調了半天,所以開個隨筆記錄一下。題目連結

思路

1.建圖
用鄰接表或者鄰接矩陣都可,我這裡用的是鄰接表,需要定義一個結構體儲存點顏色,相比鄰接矩陣要麻煩一點,但是在資料量 > 1000 時,還是建議用鄰接表。

2.統計是否有顏色重複的點
抓住“任意兩相鄰相鄰頂點不能有重複顏色”這一點,很容易想出其實就是遍歷圖的所有頂點 V,然後遍歷頂點 V 的所有出邊點,判斷這些點顏色是否和 V 相同,然後根據題目要求輸出相應結果即可。

坑點

這裡有個天坑:必須使用 K 種顏色進行填色,題目中有,但是如果不仔細看很容易漏掉(如過漏掉這點最多隻能得 1 分),對於之前沒有接觸過這種問題的我來說,更是難上加難。
然後把輸出打成全大小導致全 wa 又調了半天,還以為是程式碼有問題...

程式碼

#include <iostream>
#include <vector>

using namespace std;

const int N = 510;

struct _G{
    int color;
    vector<int> e;
}G[N];

int n, e, k, m;

int main(){
    cin >> n >> e >> k;
    
    for(int i=0; i<e; i++){
        int a, b;
        cin >> a >> b;
        G[a].e.push_back(b);
        G[b].e.push_back(a);
    }
    
    cin >> m;
    
    for(int i=0; i<m; i++){
        int color, cnt = 0, appeared[N] = {0};
        for(int j=1; j<=n; j++){
            cin >> color;
            G[j].color = color;
            appeared[color] = 1;
        }
        
        for(int j=0; j<N; j++){
            cnt += appeared[j];
        }
        
        if(cnt != k){
            cout << "No" << endl;
            continue;
        }
        
        int flag = 1;
        for(int p=1; p<=n; p++){
            int judge = 1;
            for(int q=0; q<G[p].e.size(); q++){
                if(G[p].color == G[G[p].e[q]].color){
                    judge = 0;
                    break;
                }
            }
            
            if(!judge){
                flag = 0;
                cout << "No" << endl;
                break;
            }
        }
        
        if(flag){
            cout << "Yes" << endl;
        }
    }
    
    return 0;
}