本周又做了一道图论题,感觉就是在使劲dfs。下面给出题目地址:
https://leetcode.com/problems/minimize-malware-spread/submissions/
这道题的大意是说,给定一个无向图。无向图里面有一个初始节点列表,它们都被病毒污染了。经过传然后,病毒会污染所有和污染节点连通的节点。现在从污染节点中去除一个节点(节点本身还在无向图中,只是不再污染),问去除哪个节点能使最后受污染的节点最少。如果有相同的,取序号最小的那个节点。
这道题其实不是很难。求连通分支很容易就想到dfs,并且给节点标号,同一个标号的节点属于同一个连通分支。除此之外,如果同一个连通分支有两个或以上污染点,那么这个连通分支就一定会被污染。如果连通分支只有一个污染点,那么去除这个污染点,就相当于减去了这个连通分支的节点个数。值得注意的是,污染点列表(初始列表)并不是按序号大小排序的,所以有相同的要取最小序号。还有一个坑点是有可能不存在只有一个污染点的连通分支。
下面给出程序代码:
class Solution {
public:
vector<vector<int>> graph2;
int num;
int minMalwareSpread(vector<vector<int>>& graph, vector<int>& initial) {
int i = 0, cnt = 1, ans = initial[0], maxnum = 0;
vector<int> indexs(graph.size());
vector<int> vis(graph.size() + 1);
vector<int> nums(graph.size() + 1);
graph2 = graph;
for(i=0;i<initial.size();i++)
{
num = 0;
dfs(initial[i], cnt++, indexs);
vis[indexs[initial[i]]]++;
if(vis[indexs[initial[i]]] == 1)
nums[indexs[initial[i]]] = num;
}
for(i=0;i<initial.size();i++)
{
int temp = indexs[initial[i]];
if(vis[temp]>1)
nums[temp] = 0;
if(nums[temp]>maxnum)
{
maxnum = nums[temp];
ans = initial[i];
}
else if(nums[temp]==maxnum&&initial[i]<ans)
ans = initial[i];
}
return ans;
}
void dfs(int node, int index, vector<int>& indexs)
{
int i;
if(indexs[node]!=0)
return;
indexs[node] = index;
num++;
for(i=0;i<graph2.size();i++)
{
if(i==node)
continue;
if(graph2[node][i] == 1)
dfs(i, index, indexs);
}
}
};
给出运行结果: