1134 Vertex Cover (25分)/圖的特殊存儲

題目描述

在這裏插入圖片描述
在這裏插入圖片描述

解析

我的思路是數邊數——根據給定幾個頂點,數出以這些頂點爲端點的總邊數,如果總邊數與圖的總邊數相等,那麼就滿足條件。但是由於給出的頂點集合可能有相連的情況,需要去掉重複的邊。但是這一步會將算法時間複雜度增加一個數量級,導致數據量大時運行超時。

#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<unordered_set>
#include<stack>
#include<queue>
#include<cmath>
#include<algorithm>
using namespace std;
int adj[10005];
int G[10005][10005];
int main() {
#ifdef ONLINE_JUDGE
#else
	freopen("1.txt", "r", stdin);
#endif
	int n, m; cin >> n >> m;
	for(int i=0;i<m;i++) {
		int c1, c2;
		scanf("%d%d", &c1, &c2);
		adj[c1]++; adj[c2]++; //表示以頂點爲邊的個數
		G[c1][c2] = G[c2][c1] = 1;
	}
	int k; cin >> k;
	while (k--) {
		int num; cin >> num;
		unordered_set<int> sett;
		int chongfu = 0;
		while (num--) {
			int t; scanf("%d", &t);
			for (int i : sett) if (G[i][t] == 1) chongfu++; //計算會重複計算的邊數
			sett.insert(t);
		}
		int cnt = 0;
		for (int id : sett) {
			cnt += adj[id];
		}
		cnt -= chongfu;
		printf("%s\n", cnt == m ? "Yes" : "No");
	}
	return 0;
}

看了柳神的代碼,她是用了一種特殊的方式存儲圖:用編號標識每條邊,邊屬於兩端頂點。

#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<unordered_set>
#include<stack>
#include<queue>
#include<cmath>
#include<algorithm>
using namespace std;
int main() {
#ifdef ONLINE_JUDGE
#else
	freopen("1.txt", "r", stdin);
#endif
	int n, m; scanf("%d%d", &n, &m);
	vector<vector<int>> v(n);
	for (int i = 0; i < m; i++) {
		int c1, c2;
		scanf("%d%d", &c1, &c2);
		v[c1].push_back(i);
		v[c2].push_back(i);
	}
	int k; cin >> k;
	while (k--) {
		int nv; scanf("%d", &nv);
		vector<bool> hash(m, 0);
		while (nv--) {
			int t; scanf("%d", &t);
			for (int i = 0; i < v[t].size(); i++) {
				hash[v[t][i]] = 1;
			}
		}
		int flag = 1;
		for (int i = 0; i < m; i++) {
			if (hash[i] == 0) {
				flag = 0; break;
			}
		}
		printf("%s\n", flag ? "Yes" : "No");
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章