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