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