游乐场
Time Limit:10000MS Memory Limit:65536K
Total Submit:97 Accepted:42
Case Time Limit:1000MS
Description
据新闻报道,
O
r
z
Orz
Orz教主在太平洋中央建了一个大游乐园,其中有许多小岛,每个小岛上有且仅有一个游乐设施,有的小岛与小岛之间有海底隧道连接,而有的没有,一个游乐设施对一个人只开放一次,花的钱与得到的快乐值成正比。一开始,你可以选择被空投到任意一个小岛。当你想离开游乐园时,你可以打电话叫飞机来接,但不能再次被空投。
f
h
n
fhn
fhn非常有钱,他想在游乐园里得到最大的快乐值。
而
c
z
m
czm
czm则比较穷,他的愿望只是玩最多的游乐设施。
Input
第一行:
n
n
n(代表有
n
n
n个小岛)
(
n
<
=
200
)
(n<=200)
(n<=200)
以下
n
n
n行,依次表示使用小岛
1
−
−
1--
1−−小岛
n
n
n上的游乐设施所花的钱
e
e
e (代表有
e
e
e条海底隧道)
接着
e
e
e行,每行
2
2
2个数,表示这两个小岛之间有海底隧道连接
Output
第一行,
c
z
m
czm
czm最多可以游览的游乐园的个数。
第二行,
f
h
n
fhn
fhn的游览方式所得的快乐值。
Sample Input
5
3
4
5
8
10
5
1 2
1 3
2 5
3 4
4 5
Sample Output
5
30
解题思路
与找最大连通分量.差不多。。。
注意一个游乐设施对一个人只开放一次,
也就是说他可以往回走只不过不能再玩一次这个项目而已,但是如果我们不封路的话就会死循环,所以我们可以把他可以到达的所有地方都加上,也就是连通分量了。
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int head[40000],v[400],bsy[400];
int n,e,xy,yx,k,ans=-1,ans1,s,s1;
struct c{
int x,next;
}a[40000];
void add(int x,int y)//建立邻接表
{
k++;
a[k].x=y;
a[k].next=head[x];
head[x]=k;
}
void dfs(int x){
v[x]=1;
for(int i=head[x];i;i=a[i].next)
{
if(!v[a[i].x])
{
++s;//累加游乐园的个数
s1+=bsy[a[i].x];//累加快乐值
dfs(a[i].x);
}
}
}
int main(){
scanf("%d",&n);
int x1;
for(int i=1;i<=n;i++)
cin>>bsy[i];
cin>>e;
for(int i=1;i<=e;i++)
{
scanf("%d%d",&xy,&yx);
add(xy,yx);
add(yx,xy);
}
for(int i=1;i<=n;i++)
{
if(!v[i])
{
s=1;//赋初值
s1=bsy[i];//赋初值
dfs(i);
if(s>ans1)
ans1=s;
if(s1>ans)
ans=s1;
}
}
cout<<ans1<<endl<<ans;
}