Controlling Companies

来源:互联网 发布:淘宝店铺如何添加宝贝 编辑:程序博客网 时间:2024/05/22 20:48

FJNU.1148

Description
Some companies are partial owners of other companies because they have acquired part of their total shares of stock. For example, Ford owns 12% of Mazda. It is said that a company A controls company B if at least one of the following conditions is satisfied:
1) Company A = Company B
2) Company A owns more than 50% of Company B
3) Company A controls K (K > 1) companies denoted C1, ..., CK with each company Ci owning xi% of company B and x1 + .... + xK > 50%.
Given a list of triples (i , j , p) which denote company i owning p% of company j, calculate all the pairs (h , s) in which company h controls company s. There are at most 100 companies.
Write a program to read the list of triples (i , j , p) where i , j and p are positive integers all in the range (1..100) and find all the pairs (h , s) so that company h controls company s.

Input
The input may contain several cases . Every case contain N, the number of input triples to follow . Next n line contain three integers per line as a triple (i , j , p) described above . It ends with N=0.

Output
List 0 or more companies that control other companies. Each line contains two integers that denote that the company whose number is the first integer controls the company whose number is the second integer. Order the lines in ascending order of the first integer (and ascending order of the second integer to break ties). Do not print that a company controls itself.

Sample Input
3
1 2 80
2 3 80
3 1 20

Sample Output
1 2
1 3
2 3 

My Program

#include<iostream>
#define N 101
using namespace std;
int n;
int map[N][N];
bool con[N][N];
bool out;

void depth(int v)
{
    
int i,j;
    
for(i=1;i<N;i++)
        
if(con[v][i]==false&&map[v][i]>50)
        
{
            con[v][i]
=true;
            depth(i);
            
for(j=1;j<N;j++)
                
if(con[i][j]==true)
                
{
                    con[v][j]
=true;
                    map[v][j]
=map[i][j];
                }

        }

}


void search(int v)
{
    
int i,j,t,s;
    
for(t=1;t<N;t++)
        
if(con[v][t]==false)
        
{
            s
=0;
            
for(i=1;i<N;i++)
                
if(con[v][i])
                    s
+=map[i][t];
            
if(s>50)
            
{
                
for(i=1;i<N;i++)
                    
if(con[i][v])
                    
{
                        con[i][t]
=true;
                        map[i][t]
=s;
                        
for(j=1;j<N;j++)
                            
if(con[t][j])
                            
{
                                con[i][j]
=true;
                                map[i][j]
=map[t][j];
                            }

                    }

                search(v);
            }

        }

}


int main()
{
    
int i,j;
    
int h,s,p;
    
while(cin>>n)
    
{
        
out=false;
        
if(n==0)
            
break;
        memset(map,
0,sizeof(map));
        memset(con,
false,sizeof(con));

        
for(i=0;i<n;i++)
        
{
            cin
>>h>>s>>p;
            map[h][s]
=p;
        }


        
for(i=1;i<N;i++)
        
{
            con[i][i]
=true;
            depth(i);
        }


        
for(i=1;i<N;i++)
            search(i);

        
for(i=1;i<N;i++)
            
for(j=1;j<N;j++)
                
if(i!=j&&con[i][j])
                
{
                    cout
<<i<<" "<<j<<endl;
                    
if(!out)out=true;
                }

        
if(!out)
            cout
<<0<<endl;
    }

    
return 0;
}

YOYO's Note:
┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄它是华丽的分隔线

【题意简述】

公司A控制公司B只需要满足以下三种中的任一个:
1)两公司编号相同(即A=B);
2)A公司拥有B公司50以上的股份;
3)A公司下属的子公司,它们拥有B公司股份的总额超过50。
现在给你N个公司之前的控股关系,按序号升序列出每个公司控制其他公司的情况,没有时输出0。


【粗略分析】

说是图论题,我不知道用了什么方法来做。
先深度求出直系控制的公司,然后一步步求出可以得到的子公司,
一旦得到新子公司控制权又再从头开始找一遍看是否会有新公司可控制。

【C++源代码】

#include<iostream>
#define N 101
using namespace std;
int n;
int map[N][N];
bool con[N][N];
bool out;

void depth(int v)
{
    
int i,j;
    
for(i=1;i<N;i++)
        
if(con[v][i]==false&&map[v][i]>50)
        
{
            con[v][i]
=true;
            depth(i);
            
for(j=1;j<N;j++)
                
if(con[i][j]==true)
                
{
                    con[v][j]
=true;
                    map[v][j]
=map[i][j];
                }

        }

}


void search(int v)
{
    
int i,j,t,s;
    
for(t=1;t<N;t++)
        
if(con[v][t]==false)
        
{
            s
=0;
            
for(i=1;i<N;i++)
                
if(con[v][i])
                    s
+=map[i][t];
            
if(s>50)
            
{
                
for(i=1;i<N;i++)
                    
if(con[i][v])
                    
{
                        con[i][t]
=true;
                        map[i][t]
=s;
                        
for(j=1;j<N;j++)
                            
if(con[t][j])
                            
{
                                con[i][j]
=true;
                                map[i][j]
=map[t][j];
                            }

                    }

                search(v);
            }

        }

}


int main()
{
    
int i,j;
    
int h,s,p;
    
while(cin>>n)
    
{
        
out=false;
        
if(n==0)
            
break;
        memset(map,
0,sizeof(map));
        memset(con,
false,sizeof(con));

        
for(i=0;i<n;i++)
        
{
            cin
>>h>>s>>p;
            map[h][s]
=p;
        }


        
for(i=1;i<N;i++)
        
{
            con[i][i]
=true;
            depth(i);
        }


        
for(i=1;i<N;i++)
            search(i);

        
for(i=1;i<N;i++)
            
for(j=1;j<N;j++)
                
if(i!=j&&con[i][j])
                
{
                    cout
<<i<<" "<<j<<endl;
                    
if(!out)out=true;
                }

        
if(!out)
            cout
<<0<<endl;
    }

    
return 0;
}

【注意事项】

※ 序号相同则不要输出
※ 没有输出项时要输出0
※ 是>50不是>=50

【点评】

不说点评了。。有点抽象。。
我试着把其中的search(v)改成t=0即重新开始,可是得到的结果是0.17s,比原来还多0.04s。
不知为何……

原创粉丝点击