It is vitally important to have all the cities connected by highways in a war. If a city is occupied by the enemy, all the highways from/toward that city are closed. We must know immediately if we need to repair any other highways to keep the rest of the cities connected. Given the map of cities which have all the remaining highways marked, you are supposed to tell the number of highways need to be repaired, quickly.
For example, if we have 3 cities and 2 highways connecting cit**y1-cit**y2 and cit**y1-cit**y3. Then if cit**y1 is occupied by the enemy, we must have 1 highway repaired, that is the highway cit**y2-cit**y3.
Each input file contains one test case. Each case starts with a line containing 3 numbers N (<1000), M and K, which are the total number of cities, the number of remaining highways, and the number of cities to be checked, respectively. Then M lines follow, each describes a highway by 2 integers, which are the numbers of the cities the highway connects. The cities are numbered from 1 to N. Finally there is a line containing K numbers, which represent the cities we concern.
For each of the K cities, output in a line the number of highways need to be repaired if that city is lost.
3 2 3
1 2
1 3
1 2 3
结尾无空行
1
0
0
结尾无空行
给你一个图和一些查询的节点,问你如果在图中删去查询节点,需要连几条边能使得图是连通的。
显然边数=图连通块-1.那么第一个方法就可以采用dfs来计算删去查询点后的连通块。时间复杂度为O(kn)
第二个方法是Tarjan算法,有兴趣的可以了解一下,这里就不作详细阐述了,时间复杂度为O(n+m)
#include
using namespace std;
#define CLR(arr, val) memset(arr, val, sizeof(arr))
const int N = 1e3+5;
vectorv[N];
bool vis[N];
void dfs(int x) {
vis[x] = true;
for(auto to : v[x])
if(!vis[to])
dfs(to);
}
int main() {
int n, m, k;
cin >> n >> m >> k;
while(m--) {
int a, b;
cin >> a >> b;
v[a].push_back(b);
v[b].push_back(a);
}
while(k--) {
int x, cnt = 0;
cin >> x;
CLR(vis, false);
vis[x] = true;
for(int i = 1; i <= n; i++) {
if(!vis[i]) {
dfs(i);
cnt++;
}
}
cout << cnt - 1 << endl;
}
}
#include
using namespace std;
#define INF 0x3f3f3f3f
#define CLR(arr,val) memset(arr,val,sizeof(arr))
typedef pair P;
typedef long long LL;
const int mod = 1e9+7;
const int N = 1e5+5;
vectorr[N];
int low[N], dfn[N], cut[N];
int n, m, k, a, b, ind, cnt;
bool vis[N];
void tarjan(int u, int fa) {
dfn[u] = low[u] = ++ind;
for(int i = 0; i < r[u].size(); i++) {
int v = r[u][i];
if(!dfn[v]) {
tarjan(v, u);
low[u] = min(low[u], low[v]);
if(low[v] >= dfn[u])
cut[u]++;
}
else
low[u] = min(low[u], dfn[v]);
}
if(fa < 0)
cut[u]--;
}
void solve(int n) {
for(int i = 1; i <= n; i++) {
if(!dfn[i]) {
tarjan(i, -1);
}
}
}
void dfs(int x) {
vis[x] = true;
for(auto to : r[x])
if(!vis[to])
dfs(to);
}
int main() {
cin >> n >> m >> k;
while(m--) {
cin >> a >> b;
r[a].push_back(b);
r[b].push_back(a);
}
for(int i = 1; i <= n; i++) {
if(!vis[i]) {
dfs(i);
cnt++;
}
}
solve(n);
while(k--) {
cin >> a;
cout << cnt + cut[a] - 1 << endl;
}
}