【SSL】2021-08-19 1371.控制公司

原题网址

由于某些原因,这个网址会进不去…

1371.控制公司 - 原题网址

题目描述

有些公司是其他公司的部分拥有者,因为他们获得了其他公司发行的股票的一部分。例如,福特公司拥有马自达公司 12 % 12\% 12%的股票。据说,如果至少满足了以下条件之一,公司 A A A就可以控制公司 B B B了:

  • 公司 A A A=公司 B B B
  • 公司 A A A拥有大于 50 % 50\% 50%的公司 B B B的股票。
  • 公司 A A A控制 K ( K ≥ 1 ) K(K\ge1) K(K1)个公司,记为 C 1 , . . . , C K C1,...,CK C1,...,CK,每个公司 C i Ci Ci拥有 x i % xi\% xi%的公司 B B B的股票,并且 x 1 + . . . + x K > 50 x1+...+xK>50% x1+...+xK>50

你将被给予一系列的三对数 ( i , j , p ) (i,j,p) (i,j,p),表明公司 i i i享有公司 j j j p % p\% p%的股票。计算所有的数对 ( h , s ) (h,s) (h,s),表明公司 h h h控制公司 s s s。至多有 100 100 100个公司。

写一个程序读入三对数 ( i , j , p ) (i,j,p) (i,j,p) i , j i,j i,j p p p是都在范围 ( 1...100 ) (1...100) (1...100)的正整数,并且找出所有的数对 ( h , s ) (h,s) (h,s),使得公司 h h h控制公司 s s s

格式

输入格式

第一行: N N N,表明接下来三对数的数量。
第二行到第 N + 1 N+1 N+1行: 每行三个整数作为一个三对数 ( i , j , p ) (i,j,p) (i,j,p),如上文所述。

输出格式

输出零个或更多个的控制其他公司的公司。每行包括两个整数表明序号为第一个整数的公司控制了序号为第二个整数的公司。将输出的每行以第一个数字升序排列(并且第二个数字也升序排列来避免并列)。请不要输出控制自己的公司。

样例

输入样例

3
1 2 80
2 3 80
3 1 20

输出样例

1 2
1 3
2 3

解题思路

这道题稍微有点复杂,写注释时有点懵…
解题思路是这样的:
首先,这道题是要用 d f s dfs dfs(深度优先搜索) 做,搜索时只需要一个参数 c c c,表示公司代表的数字,因为主要的数据是全局变量需要在每次嵌套搜索时计算和使用

Code

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<cstring>
#include<string>
#include<map>
#include<queue>
#define maxn 100
using namespace std;
int gf[maxn + 1][maxn + 1], has[maxn + 1], cnt[maxn + 1], n, cn, a, b, g, ctl[maxn + 1];
// gf[i][j]表示i公司自己占有j公司多少股份,has[i]表示搜索时的c公司是否占有i公司,
// cnt[i]表示搜索时的c公司占有i公司多少股份,ctl[i]表示搜索时的c公司和子公司是否占有i公司 
void init()
{
	int mx = 0;
	cin>>n;
	for (int i = 1; i <= n; i ++)
	{
		cin>>a>>b>>g;
		mx = max(mx, max(a, b));
		// mx统计总共有多少个公司(因为n只表示三对数的数量,不表示公司数量) 
		gf[a][b] = g;
	}
	n = mx;
}

void oput(int i)
{
	for (int j = 1; j <= n; j ++) if (i!=j&&has[j]) cout<<i<<" "<<j<<endl;
}

void dpfs(int c)
{
	if (ctl[c]) return;
	ctl[c] = 1;
	for (int i = 1; i <= n; i ++)
	{
		if (i == c) continue;
		cnt[i] += gf[c][i];
		if (cnt[i] > 50)
		{
			has[i] = 1;
			dpfs(i);
		}
	}
}

void comp()
{
	for (int i = 1; i <= n; i ++)
	{
		memset(has, 0, sizeof(has));
		memset(cnt, 0, sizeof(cnt));
		memset(ctl, 0, sizeof(ctl));
		dpfs(i);
		oput(i);
	}
}

int main()
{
	init();
	comp();
	return 0;
} 

大功告成 ∼ \sim

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值