洛谷P1475[控制公司]题解

题目传送门

这题如果不加思考直接用 dfs 一定会错。

为什么会这样呢,于是我们画了张图:

这张图里节点 \(1\) 控制了节点 \(2,6\),节点 \(2,6\) 又同时控制了节点 \(3\),同时节点 \(3\) 有节点 \(5\)\(30\%\) 股票,显然节点 \(1\) 是无法控制节点 \(5\) 的,但我们的dfs程序会将节点 \(3\) 有节点 \(5\)\(30\%\) 股票同时传递给节点 \(2,6\) 让节点 \(1\)\(60\%\),因此出错。

简单来说就是直接用 dfs 会重复统计

于是我们考虑换一种 dfs 的策略,先考虑能直接控制的公司,然后打上标记,防止再被统计,于是我们就 AC 了这道题。

方法慢了点,但易理解很多。

#include<iostream>
#include<vector>
using namespace std;
int G[200][200],control[1000][1000];
//G代表初始情况,control[i][j]代表i实际上有j的control[i][j]的股票
bool vis[1000][1000];
void dfs(int u,int v){
	vis[u][v]=1;
	for(int i=1;i<=100;++i){
		control[u][i]+=G[v][i];
		if(control[u][i]>50&&!vis[u][i])
			dfs(u,i);
	}
}
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;++i)
		int u,v,dis;
		cin>>u>>v>>dis;
		G[u][v]=dis;
		control[u][v]=dis;
	}
	for(int i=1;i<=100;++i)
		for(int j=1;j<=100;++j)
			if(i!=j&&G[i][j]>50&&!vis[i][j])//如果超过50才有可能更新
				dfs(i,j);
	for(int i=1;i<=100;++i)
		for(int j=1;j<=100;++j)
			if(i!=j&&control[i][j]>50)cout<<i<<" "<<j<<endl;
	return 0;
} 

蒟蒻第一次交题解,有错误请指出哦

posted @ 2021-04-17 11:51  endlessloop  阅读(49)  评论(0)    收藏  举报