• [CSAcademy]Virus on a Tree


    [CSAcademy]Virus on a Tree

    题目大意:

    给你一棵(n(nle10^5))个点的树,一开始点(1)有病毒,可以沿着边扩散。你可以事先切掉若干条边,使得病毒扩散不超过(k)个结点。告诉你哪些边可以切,问最少需要切掉多少条边。

    思路:

    (1)开始DFS,碰到一条可以切的边就返回。将得到的边按照子树大小排序,把能加上的边都加回去。

    源代码:

    #include<queue>
    #include<cstdio>
    #include<cctype>
    #include<vector>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    const int N=1e5+1;
    struct Edge {
    	int to;
    	bool w;
    };
    std::vector<Edge> e[N];
    inline void add_edge(const int &u,const int &v,const bool &w) {
    	e[u].push_back((Edge){v,w});
    	e[v].push_back((Edge){u,w});
    }
    int size[N],tot;
    std::priority_queue<int,std::vector<int>,std::greater<int> > q;
    void dfs(const int &x,const int &par,const bool &flag) {
    	size[x]=1;
    	for(unsigned i=0;i<e[x].size();i++) {
    		const int &y=e[x][i].to;
    		if(y==par) continue;
    		if(flag||!e[x][i].w) {
    			dfs(y,x,flag);
    			size[x]+=size[y];
    		} else {
    			dfs(y,x,true);
    			q.push(size[y]);
    		}
    	}
    }
    int main() {
    	const int n=getint(),m=getint();
    	for(register int i=1;i<n;i++) {
    		const int u=getint(),v=getint();
    		add_edge(u,v,getint());
    	}
    	dfs(1,0,0);
    	int tot=size[1];
    	while(!q.empty()) {
    		if(tot+q.top()>m) break;
    		tot+=q.top();
    		q.pop();
    	}
    	const int ans=q.size();
    	printf("%d
    ",tot<=m?ans:-1);
    	return 0;
    }
    
  • 相关阅读:
    构建之法阅读笔记
    人月神话阅读笔记
    人月神话阅读笔记2
    人月神话阅读笔记
    第十周总结
    第九周总结
    进度日报10
    进度日报8
    进度日报7
    进度日报6
  • 原文地址:https://www.cnblogs.com/skylee03/p/10141114.html
Copyright © 2020-2023  润新知