从半年前开始,我对这道题产生了极大的恐惧,作为蒟蒻的我,好难啊,现在学了邻接表,一切so easy。
题目
公司A控制公司B的原则
- 公司A拥有大于50%的公司B的股票。
- 公司A控制K(K >= 1)个公司,记为C1至CK,每个公司Ci拥有xi%的公司B的股票,并且 ∑ x 1 x k \sum^{xk}_{x1} ∑x1xk>50%。
输出若干个的控制其他公司的公司。每行包括两个整数表明第一个整数的公司控制了第二个整数的公司。将输出的每行以第一个数字升序排列,并且第二个数字也升序排列。
分析
这道题用深搜,广搜都行,如果>50%那么往后并标记
深搜代码
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define N 100
using namespace std;
struct node{
int x,y,w,next;
}e[N*100+1]; bool v[N+1];
int n,dis[N+1],ls[N+1];
int in(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
void dfs(int i){
int t=ls[i];
while (t){//增加
dis[e[t].y]+=e[t].w;
t=e[t].next;
}
t=ls[i];
while (t){
if (dis[e[t].y]>50&&!v[e[t].y]){//属于被控制的吗?
v[e[t].y]=1;
dfs(e[t].y);
v[e[t].y]=0;
}
t=e[t].next;
}
}
int main(){
n=in();
for (int i=1;i<=n;i++) e[i].x=in(),e[i].y=in(),e[i].w=in(),e[i].next=ls[e[i].x],ls[e[i].x]=i;//邻接表
for (int i=1;i<=100;i++)
if (ls[i]){//可以往下走
memset(dis,0,sizeof(dis));
v[i]=1; dfs(i); v[i]=0;
for (int j=1;j<=100;j++)
if (dis[j]>50&&i!=j) printf("%d %d\n",i,j);//公司被控制
}
return 0;
}
#广搜代码
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define N 100
using namespace std;
struct node{
int x,y,w,next;
}e[N*100+1]; bool v[N+1];
int n,dis[N+1],ls[N+1];
int in(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
void spfa(int st){//名字怪异,不要在意
int head=0,tail=1,list[N+1]; list[1]=st;
do{
head=head%N+1;//出队
int t=ls[list[head]];
while (t){
dis[e[t].y]+=e[t].w;
if (dis[e[t].y]>50&&!v[e[t].y]){//加入队列
v[e[t].y]=1;
tail=tail%N+1;
list[tail]=e[t].y;
}
t=e[t].next;
}
}while (head!=tail);
}
int main(){
n=in();
for (int i=1;i<=n;i++) e[i].x=in(),e[i].y=in(),e[i].w=in(),e[i].next=ls[e[i].x],ls[e[i].x]=i;
for (int i=1;i<=100;i++)
if (ls[i]){
memset(dis,0,sizeof(dis));
memset(v,0,sizeof(v));
v[i]=1; spfa(i);
for (int j=1;j<=100;j++)
if (dis[j]>50&&i!=j) printf("%d %d\n",i,j);
}
return 0;
}