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;
    }
};








![[网鼎杯2018]Unfinish解题,五分钟带你解题](https://i-blog.csdnimg.cn/direct/417e3d3eee5b4d1186807a629824e8cc.png)










