LeetCode2368 受限条件下可到达节点的数目
class Solution {
public:
int dfs(vector<vector<int>>& g,int x,int fa){
int sum=1;
for(int y:g[x]){
if(y!=fa) sum+=dfs(g,y,x);
}
return sum;
}
int reachableNodes(int n, vector<vector<int>>& edges, vector<int>& restricted) {
vector<vector<int>> g(n);
unordered_set<int> s;
for(int i=0;i<restricted.size();i++) s.insert(restricted[i]);
for(int i=0;i<edges.size();i++){
int x=edges[i][0],y=edges[i][1];
if(!s.count(x)&&!s.count(y)){//两节点都不受限才建立边
g[x].push_back(y);
g[y].push_back(x);
}
}
return dfs(g,0,-1);
}
};
时间复杂度:O(n)
空间复杂度:O(n)
LeetCode2477 到达首都的最少油耗(贡献法)
/*
* @lc app=leetcode.cn id=2477 lang=cpp
*
* [2477] 到达首都的最少油耗
*/
// @lc code=start
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
class Solution {
public:
long long res=0;
int sum=0;
int dfs(vector<vector<int>>& g,int x,int fa,int seats){
int sum=1;
for(int y:g[x]){
if(y!=fa){ //递归子节点,不能递归父节点
sum+=dfs(g,y,x,seats); //统计子树大小
}
}
if(x!=0) //x不是根节点
res+=(sum-1)/seats+1; //ceil(sum*1.0/seats);
return sum;
}
long long minimumFuelCost(vector<vector<int>>& roads, int seats) {
int n=roads.size()+1;
vector<vector<int>> g(n);
for(int i=0;i<roads.size();i++){
int from=roads[i][0],to=roads[i][1];
g[from].push_back(to);
g[to].push_back(from);
}
dfs(g,0,-1,seats);
return res;
}
};
时间复杂度:O(n)
空间复杂度:O(n)
LeetCode924 尽量减少恶意软件的传播
class Solution {
public:
int minMalwareSpread(vector<vector<int>>& graph, vector<int>& initial) {
int n=graph.size();
vector<int> ids(n,0); //ids[i]表示节点i所在的连通分量
unordered_map<int,int> id_size; //连通分量id, 大小
int id=1;
int size;
function<void(int)> dfs=[&](int x){
size++;
ids[x]=id;
for(int y=0;y<n;y++){
if(ids[y]==0&&graph[x][y]==1){
dfs(y);
}
}
};
for(int i=0;i<n;i++){
if(ids[i]==0){ //该节点未被访问过
size=0;
dfs(i);
id_size[id]=size;
id++;
}
}
int m=initial.size();
vector<int> sum(n,0); //sum[i]表示将节点i从已感染节点中删除,能够减少的感染节点数
for(int i=0;i<m;i++){
sum[initial[i]]=id_size[ids[initial[i]]];
}
for(int i=0;i<m;i++){//如果已感染节点x,y在同一连通分量中,sum[x]=0,sum[y]=0
for(int j=i+1;j<m;j++){
int x=initial[i],y=initial[j];
if(ids[x]==ids[y]){
sum[x]=0;
sum[y]=0;
}
}
}
int res=initial[0];
for(int i=0;i<m;i++){
int x=initial[i];
if(sum[x]>sum[res]||sum[x]==sum[res]&&x<res) res=x;
}
return res;
}
};