USACO-Section2.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个公司。
写一个程序读入三对数(i,j,p),i,j和p是都在范围(1..100)的正整数,并且找出所有的数对(h,s),使得公司h控制公司s。

INPUT FORMAT

第一行: N,表明接下来三对数的数量。{即(i,j,p)的数量}
第二行到第N+1行: 每行三个整数作为一个三对数(i,j,p),如上文所述。{表示公司 i 拥有公司j p%的股份}


SAMPLE INPUT (file concom.in)

3
1 2 80
2 3 80
3 1 20


OUTPUT FORMAT

输出零个或更多个的控制其他公司的公司。每行包括两个整数A、B,表示A公司控制了B公司。将输出的数对以升序排列。
请不要输出控制自己的公司。


SAMPLE OUTPUT (file concom.out)

1 2
1 3
2 3


解题思路:

将初始的控股信息保存到一个二维数组G中,再新建一个二维数组ans复制一的信息。遍历ans数组,如果大于ans[i][j]>50,则dfs(i,j),将控制的公司的股票加在自己上面。如果之前i控制k公司的股票<=50,加上了j对k公司的股票后大于了50,则dfs(i,k),从而保证不重不漏。

/*
ID: huanshi
LANG: C
TASK: concom
*/
#include
#include
#include
#include
int G[110][110],ans[110][110];
int n,length;
void dfs(int i,int j)
{
    for (int k=1;k<=length;k++)
        if (i!=k && ans[i][k]<=50)
        {
            ans[i][k]+=G[j][k];
            if (ans[i][k]>50) dfs(i,k);
        }
}
int main()
{
    FILE *fin  = fopen ("concom.in", "r");
    FILE *fout = fopen ("concom.out", "w");
    fscanf(fin,"%d",&n);
    length=0;
    memset(G,0,sizeof(G));
    for (int i=1;i<=n;i++)
    {
        int a,b,c;
        fscanf(fin,"%d%d%d",&a,&b,&c);
        G[a][b]=c;
        if (a>length) length=a; 
        if (b>length) length=b;
    }
    memcpy(ans,G,sizeof(int)*110*110);
    for (int i=1;i<=length;i++)
        for (int j=1;j<=length;j++)
            if (ans[i][j]>50) dfs(i,j);
    for (int i=1;i<=length;i++)
        for (int j=1;j<=length;j++)
            if (i!=j && ans[i][j]>50)
                fprintf(fout,"%d %d\n",i,j);
    exit(0);
}

你可能感兴趣的:(USACO)