PAT_甲級_1134 Vertex Cover (25point(s)) (C++)【散列】

目錄

1,題目描述

題目大意

2,思路

3,AC代碼

4,解題過程

第二搏


1,題目描述

  • vertex cover:頂點覆蓋; 點集覆蓋問題;
  • incident:發生的事情(尤指不尋常的或討厭的); 嚴重事件,暴力事件(如犯罪、事故、襲擊等); (兩國間的) 摩擦,衝突; (常指) 軍事衝突; 

Sample Input:

10 11
8 7
6 8
4 5
8 4
8 1
1 2
1 4
9 8
9 1
1 0
2 4
5
4 0 3 8 4
6 6 1 7 5 4 9
3 1 8 4
2 2 8
7 9 8 7 6 5 4 2

 

Sample Output:

No
Yes
Yes
No
No

題目大意

 判斷給定的序列是否爲vertex cover(一個特殊的頂點集,要求圖中每條邊中至少有一個頂點在此集合中),輸出Yes或輸出No。

 

2,思路

聲明一個unordered_map<int, unordered_set<int>> data存放每個頂點連接的邊,查詢時,將所有頂點在data中對應的值存入set中,若set.size()==M就輸出Yes,否則輸出No。

 

3,AC代碼

#include<bits/stdc++.h>
using namespace std;

unordered_map<int, unordered_set<int>> data;
int main(){
#ifdef ONLINE_JUDGE
#else
    freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
    int N, M, K, v1, v2, num;//N頂點數 M邊數 K查詢數
    scanf("%d%d", &N, &M);
    for(int i = 0; i < M; i++){
        scanf("%d%d", &v1, &v2);
        data[v1].insert(i);
        data[v2].insert(i);
    }
    scanf("%d", &K);
    unordered_set<int> temp;
    for(int i = 0; i < K; i++){
        scanf("%d", &num);
        temp.clear();// !!!
        for(int j = 0; j < num; j++){
            scanf("%d", &v1);
            for(auto it : data[v1])
                temp.insert(it);
        }
        if(temp.size() == M)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

4,解題過程

本想着先來一套最樸實的做法

然後準備想着怎麼優化了。。。

然而

 題目限制600ms

苟過了一題。。。

第二搏

欣賞了一位大佬的做法,時間快了一倍,佔用內存還比較少。

精彩

@日沉雲起【pat甲級1134. Vertex Cover (25)】


#include<bits/stdc++.h>
using namespace std;
int N,M,K;
bool vertex[10005];//散列數組
int main(){
    scanf("%d%d",&N,&M);
    pair<int,int>edge[M];//邊的數組
    for(int i=0;i<M;++i)//讀取邊
        scanf("%d%d",&edge[i].first,&edge[i].second);
    scanf("%d",&K);
    while(K--){
        int A,a;
        scanf("%d",&A);
        memset(vertex,0,sizeof(vertex));//將vertex元素均置false
        while(A--){//讀取點集
            scanf("%d",&a);
            vertex[a]=true;//將vertex數組中對應元素置true
        }
        bool f=true;//標誌輸出應該爲true還是false
        for(int i=0;i<M&&f;++i)//遍歷邊的數組
            if(!vertex[edge[i].first]&&!vertex[edge[i].second])//有邊兩個端點在vertex中均爲false
                f=false;//置f爲false
        printf("%s\n",f?"Yes":"No");//輸出
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章