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

本文解析了USACO竞赛中Concom题目的解题思路及算法实现过程,通过使用队列提升效率并避免重复计算,实现了对公司掌控关系的有效更新。

开始我对于第三条的理解是可以传递更新的..比如说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; }

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值