USACO Section 2.3 Controlling Companies - 题意要理解清楚..

    开始我对于第三条的理解是可以传递更新的..比如说A掌控B..B掌控C..而这时发现C可以掌控D..那么D的股权要加给A,B,C...但一个是不好写...再一个是时间效率差..交上去还WA了..还好USACO提供了数据...根据出错的数据..才发现题目的这个传递没有这种关系..就向前面的例子..只有C要加上D的股权...

    这样就好写了..并且可以用队列来提高效率..因为只有更新过某点的值~~这个点才有可能拥有了新的公司...但要注意题目的自己掌控自己不要输出~~所以输出要判断下...


Program:

/*  
ID: zzyzzy12  
LANG: C++  
TASK: concom
*/    
#include<iostream>    
#include<stdio.h>    
#include<string.h>    
#include<math.h>    
#include<stack>
#include<algorithm>    
#include<queue> 
using namespace std;    
struct node
{
     int a,b;      
}h,k;
int n,i,j,p,x,y,mar[110][110],ans[110][110];
bool own[105][105],add[105][105];
queue<node> myqueue;
int main()
{
     freopen("concom.in","r",stdin);
     freopen("concom.out","w",stdout);         
     memset(mar,0,sizeof(mar));
     memset(own,false,sizeof(own)); 
     memset(add,false,sizeof(add));
     memset(ans,0,sizeof(ans));
     while (!myqueue.empty()) myqueue.pop();
     scanf("%d",&n);
     while (n--)
     {
             scanf("%d%d%d",&i,&j,&p);
             if (i==j) continue; 
             ans[i][j]=mar[i][j]=p;  
             if (p>50)
             {
                    h.a=i; h.b=j;
                    own[i][j]=true;
                    myqueue.push(h);
             }
     }
     while (!myqueue.empty())
     {
             h=myqueue.front();
             myqueue.pop();
             for (i=1;i<=100;i++) 
             if (!own[h.a][i])
             {
                    if (!add[h.a][h.b]) ans[h.a][i]+=mar[h.b][i];
                    if (ans[h.a][i]>50) 
                    {
                           k.a=h.a; k.b=i;
                           own[h.a][i]=true;
                           myqueue.push(k);
                    }
             }
             add[h.a][h.b]=true;
             for (i=1;i<=100;i++)
             if (own[i][h.a] && !add[i][h.b])
             {
                   add[i][h.b]=true;              
                   for (j=1;j<=100;j++)
                   if (!own[i][j])
                   {
                         add[i][h.b]=true;        
                         ans[i][j]+=mar[h.b][j];
                         if (ans[i][j]>50) 
                         {
                                k.a=i; k.b=j;
                                own[i][j]=true;
                                myqueue.push(k);
                         }                         
                   }
             }
     }
     for (i=1;i<=100;i++)
        for (j=1;j<=100;j++)
           if (own[i][j] && i!=j) printf("%d %d\n",i,j);
     return 0;   
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值