您的位置:首页 > 理论基础 > 计算机网络

【CCF】网络延时

2015-09-12 11:08 471 查看
试题名称: 网络延时

时间限制: 1.0s

内存限制: 256.0MB

问题描述:

问题描述

  给定一个公司的网络,由n台交换机和m台终端电脑组成,交换机与交换机、交换机与电脑之间使用网络连接。交换机按层级设置,编号为1的交换机为根交换机,层级为1。其他的交换机都连接到一台比自己上一层的交换机上,其层级为对应交换机的层级加1。所有的终端电脑都直接连接到交换机上。

  当信息在电脑、交换机之间传递时,每一步只能通过自己传递到自己所连接的另一台电脑或交换机。请问,电脑与电脑之间传递消息、或者电脑与交换机之间传递消息、或者交换机与交换机之间传递消息最多需要多少步。

输入格式

  输入的第一行包含两个整数n, m,分别表示交换机的台数和终端电脑的台数。

  第二行包含n - 1个整数,分别表示第2、3、……、n台交换机所连接的比自己上一层的交换机的编号。第i台交换机所连接的上一层的交换机编号一定比自己的编号小。

  第三行包含m个整数,分别表示第1、2、……、m台终端电脑所连接的交换机的编号。

输出格式

  输出一个整数,表示消息传递最多需要的步数。

样例输入

4 2

1 1 3

2 1

样例输出

4

样例说明

  样例的网络连接模式如下,其中圆圈表示交换机,方框表示电脑:



  其中电脑1与交换机4之间的消息传递花费的时间最长,为4个单位时间。

样例输入

4 4

1 2 2

3 4 4 4

样例输出

4

样例说明

  样例的网络连接模式如下:



  其中电脑1与电脑4之间的消息传递花费的时间最长,为4个单位时间。

评测用例规模与约定

  前30%的评测用例满足:n ≤ 5, m ≤ 5。

  前50%的评测用例满足:n ≤ 20, m ≤ 20。

  前70%的评测用例满足:n ≤ 100, m ≤ 100。

  所有评测用例都满足:1 ≤ n ≤ 10000,1 ≤ m ≤ 10000。

提交上去尝试一下,结果通过了。时间800ms,感觉略久。

第一题的存储方式

1 2

1 3

3 4

2 5

1 6

第二题的存储方式

1 2

2 3

2 4

3 5

4 6

4 7

4 8

使用memset还是显示编译错误....为什么...?

#include<iostream>
using namespace std;

//next表示当前结点指向的结点的编号
//p表示搜索停下的位置
struct L{
int next,p;
};

int tree[20000][2];//0 ~ n + m - 2  length = n + m - 1 连接的两个结点的集合
int *amount;// 0 ~ n + m - 1   length = n + m  第一次深度搜索递归的时候用到,表示该结点有多少子结点
int n,m;//输入的两个数字
int e;//第一次深度搜索递归遍历找到的路径最长的结点
int max_dist = -1;//最长距离
bool *visit;//第二次深度搜索递归的时候需要用到,哪些结点已经访问

//第一次深度搜索递归的时候用到,在tree数组左边一列中找对应的结点编号,返回指向的结点编号和当前搜索停下的位置
L find(int index,L l){
int i = l.p;
for(;++i<n+m-1;){
if( index + 1 == tree[i][0]){
l.next = tree[i][1];
l.p = i;
break;
}
}
return l;
}

//第一次深度搜索递归
void dfs(int index,int dist){//index 0 →
int i = -1;
L l;
l.next = -1;
l.p = -1;
if(max_dist < dist){
e = index;
max_dist = dist;
}
//	 cout<<index + 1<<" "<<dist<<endl;
for(;++i<amount[index];){
l = find(index,l);
dfs(l.next - 1,dist+1);
}

}

//第二次深度搜索递归。差别在于左边一列和右边一列都要搜索,还要注意指向的结点是否已经访问到
L find1(int index,L l){
int i = l.p;
for(;++i<n+m-1;){
l.p = i;
if( index + 1 == tree[i][0] && !visit[tree[i][1]-1]){
l.next = tree[i][1];
break;
}
else if( index + 1 == tree[i][1]  && !visit[tree[i][0]-1]){
l.next = tree[i][0];
break;
}
}
return l;
}

//第二次深度搜索递归,需要注意l.next的初始化(-1)以及访问的结点需要进行标记
void dfs1(int index,int dist){//index 0 →
int i = -1;
L l;
l.next = -1;
l.p = -1;
if(max_dist < dist){
e = index;
max_dist = dist;
}
visit[index] = 1;
//	 cout<<index + 1<<" "<<dist<<endl;
while(l.p<n+m-2){
l.next = -1;
l = find1(index,l);
if(l.next!=-1){
dfs1(l.next - 1,dist+1);
}
}
}

int main(){
int i,x;
cin>>n>>m;
amount = new int[n+m];
visit = new bool[n+m];
for(i = -1;++i<n+m;){
visit[i] = 0;
amount[i] = 0;
}
//	 memset(visit,0,(n+m)*sizeof(bool));
//	 memset(amount,0,(n+m)*sizeof(amount));
for(i=-1;++i<n+m-1;){
cin>>x;
tree[i][0] = x;
tree[i][1] = i + 2;
amount[x-1]++;
}
dfs(0,0);
//	 max_dist = 0;
dfs1(e,0);
cout<<max_dist<<endl;
delete[]amount;
delete[]visit;
//	 system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: