[USACO][Section 2.3][搜索] Controlling Companies

题目大意


有些公司是其他公司的部分拥有者,因为他们获得了其他公司发行的股票的一部分。例如,福特公司拥有马自达公司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。 
        {
            map[x][i]+=map[y][i];
            if(map[x][i]>50&&inow,func()会在后面调用update(x,i,i),不需要现在更新。 
                update(x,i,now);
        }
}

void func(int x)
//检查x公司的控股情况 
{
    for(int i=1;i<=size;i++)
        if(i!=x&&map[x][i]>50)
            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	

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注