zoukankan      html  css  js  c++  java
  • USACO / Controlling Companies (类似BFS)

    题目    

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

    1. 公司A = 公司B。
    2. 公司A拥有大于50%的公司B的股票。
    3. 公司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。

    输入格式

    第一行: N,表明接下来三个数的数量,即(i,j,p)的数量。

    第二行到第N+1行: 每行三个整数作为一个三对数(i,j,p),表示i公司拥有j公司 p%的股份。

    样例输入 (file concom.in)

    3
    1 2 80
    2 3 80
    3 1 20
    

    输出格式

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

    请不要输出控制自己的公司(应该是不输出自己,互相控制的公司还是要输出的)。

    样例输出 (file concom.out)

    1 2
    1 3
    2 3
    分析:
    这道题刚开始自己看着还挺麻烦,不想写。不过仔细研究一下就发现是个很简单的搜索题。
    设f[i][j]是i公司直接控j公司多少股,p[i][j]是i公司直接+间接控j公司多少股,h[i][j]表示i公司是否可以控制j公司。
    首先把所有直接可以控制的关系添加进去,然后开始枚举更新所有公司的间接持股,没枚举完一次就判断是否添加了新控制关系,而每添加一组控制关系就要再把所有的关系更新一遍(看到这里我就突然想到了Dijkstra,每确定一个点都要松弛一次,然后恍然大悟,学算法不仅要理解表面,还要学习它里面包含的思想~~~
    代码:

    /*
    ID: 138_3531
    PROB: concom
    LANG: C++
    */
    #include<iostream>
    #include<fstream>
    #include<cstring>
    
    
    using namespace std;
    
    
    int f[101][101],p[101][101];
    char h[101][101];
    int n;
    
    
    
    
    ifstream fin("concom.in");
    ofstream fout("concom.out");
    
    
    int main()
    {
        int max=0;
        fin>>n;
        memset(h,0,sizeof(h));
        memset(f,0,sizeof(f));
        for (int i=0;i<n;i++)
        {
            int x,y;
            fin>>x>>y;
            if (x>max) max=x;
            if (y>max) max=y;
            fin>>f[x][y];
            if (f[x][y]>50)
                h[x][y]=1;
        }
        int ok=1;
        while (ok)            
        {
            ok=0;
            memset(p,0,sizeof(p));
            for (int i=1;i<=max;i++)
                for (int j=1;j<=max;j++)
                    p[i][j]=f[i][j];
            for (int i=1;i<=max;i++)
                for (int j=1;j<=max;j++)
                    if (h[i][j])
                        for (int k=1;k<=max;k++)
                            p[i][k]+=f[j][k];
            for (int i=1;i<=max;i++)
                for (int j=1;j<=max;j++)
                    if ((p[i][j]>50)&&(h[i][j]==0))
                    {
                        h[i][j]=1;
                        ok=1;
                    }
    
    
        }
    
    
    
    
        for (int i=1;i<=max;i++)
            for (int j=1;j<=max;j++)
                if ((h[i][j])&&(i!=j))
                    fout<<i<<' '<<j<<endl;
        return 0;
    }
     
    举杯独醉,饮罢飞雪,茫然又一年岁。 ------AbandonZHANG
  • 相关阅读:
    Word Frequency
    House Robber(动态规划)
    链表的排序 时间复杂度O(nlogn)
    gdb调试(转)
    c实现的trim函数
    c实现的trim函数
    mac下安装pyQt4
    哈夫曼编码详解
    IOS7--javascriptcore中jscontext使用要注意的一点
    Docker mysql 连接 “The server requested authentication method unknown to the clien”错误
  • 原文地址:https://www.cnblogs.com/AbandonZHANG/p/2598503.html
Copyright © 2011-2022 走看看