洛谷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;
}
蒟蒻第一次交题解,有错误请指出哦