题目大意
有些公司是其他公司的部分拥有者,因为他们获得了其他公司发行的股票的一部分。例如,福特公司拥有马自达公司12%的股票。据说,如果至少满足了以下三个条件之一,公司A就可以控制公司B了:
- 公司A = 公司B。
- 公司A拥有大于50%的公司B的股票。
- 公司A控制K(K >= 1)个公司,记为C1, …, CK,每个公司Ci拥有xi%的公司B的股票,并且x1+ …. + xK > 50%。
给你一个表,每行包括三个数(i,j,p);表明公司i享有公司j的p%的股票。计算所有的数对(h,s),表明公司h控制公司s。至多有100个公司。写一个程序读入N组数(i,j,p),i,j和p是都在范围(1..100)的正整数,并且找出所有的数对(h,s),使得公司h控制公司s。
思路
搜索。若公司a可以控制公司b,就将b的控股信息更新到a上,若发现有新的公司c可以被a所控制,则再把c的信息更新到a上,这由一个递归过程来体现。搜索完成后将结果排序输出即可。
代码
/*
ID: lujunda1
LANG: C++
PROG: concom
*/
#include
#include
#include
using namespace std;
#define size 100
int map[size+1][size+1],n;
//map[i][j]==x表示i公司持有j的x%的股份。
int res[size*size][2],total;
//res[][]存储结果,total是结果的数量。
void init()
//初始化
{
memset(map,0,sizeof(map));
total=0;
}
void update(int x,int y,int now)
//x公司控制y公司,将y公司持股信息更新到x公司上。
//now表示func函数的进度,用于避免重复计算。
{
res[total][0]=x;
res[total++][1]=y;
//x控制y公司,先更新res数组。
for(int i=1;i<=size;i++)
if(i!=x&&map[x][i]<=50)
//只需要更新那些尚未被x控制的公司的信息即可。所以map[x][i]50&&i<now)
//如果inow,func()会在后面调用update(x,i,i),不需要现在更新。
update(x,i,now);
}
}
void func(int x)
//检查x公司的控股情况
{
for(int i=1;i50)
update(x,i,i);
}
int cmp(const void* m,const void* n)
//对二维数组res排序
{
if(*(int*)m==*(int*)n)
return *((int*)m+1)-*((int*)n+1);
return *(int*)m-*(int*)n;
}
int main()
{
freopen("concom.in","r",stdin);
freopen("concom.out","w",stdout);
init();
scanf("%d",&n);
for(int i,j,k;n--;)
{
scanf("%d%d%d",&i,&j,&k);
map[i][j]=k;
}
for(int i=1;i<=size;i++)
func(i);
qsort(res,total,sizeof(res[0]),cmp);
//对结果进行排序。
for(int i=0;i<total;i++)
printf("%d %d\n",res[i][0],res[i][1]);
}