您的位置:首页 > Web前端

05-树8 File Transfer

2016-04-21 16:10 295 查看
05-树8 File Transfer (25分)

We have a network of computers and a list of bi-directional connections. Each of these connections allows a file transfer from one computer to another. Is it possible to send a file from any computer on the network to
any other?


Input Specification:

Each input file contains one test case. For each test case, the first line contains NN (2\le
N\le 10^42≤N≤10​4​​),
the total number of computers in a network. Each computer in the network is then represented by a positive integer between 1 and NN.
Then in the following lines, the input is given in the format:
I c1 c2

where
I
stands
for inputting a connection between
c1
and
c2
;
or
C c1 c2

where
C
stands
for checking if it is possible to transfer files between
c1
and
c2
;
or
S

where
S
stands
for stopping this case.


Output Specification:

For each
C
case,
print in one line the word "yes" or "no" if it is possible or impossible to transfer files between
c1
and
c2
,
respectively. At the end of each case, print in one line "The network is connected." if there is a path between any pair of computers; or "There are
k
components."
where
k
is the number of connected components
in this network.


Sample Input 1:

5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
S


Sample Output 1:

no
no
yes
There are 2 components.


Sample Input 2:

5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
I 1 3
C 1 5
S


Sample Output 2:

no
no
yes
yes
The network is connected.


题目思路:

实际上就是并查集,关键是要进行路径压缩,以下这个是何老师讲的方法没有进行路径压缩

#include<stdio.h>
#include<string.h>
#include<math.h>

#define MAXN 10001
#define MINH -1
#define ElementType int

typedef struct{
ElementType Data;
float Parent;
}SetType;

SetType H[MAXN];//建立堆

void CreateSetType(int N)
{

for(int i = 0; i < N; i++)
{
H[i].Data = i+1;
H[i].Parent = -1;

}

}

int Find(SetType S[],ElementType X)
{
//在数组S中查找值为X的元素所属的集合
//MAXN为全局变量,为数组S的最大长度
int i;
for( i = 0; i < MAXN&&S[i].Data != X;i++);
if(i > MAXN){
return -1;//未找到X,返回-1
}
for(;S[i].Parent >=0; i = S[i].Parent);
return i;//找到X所属集合,返回树根节点在数组S中的下标

}

void Union(SetType S[], ElementType X1,ElementType X2)
{
int Root1,Root2;
Root1 = Find(S,X1);
Root2 = Find(S,X2);

if( Root1 != Root2 )
{
int root1,root2;
root1 = fabs(S[Root1].Parent);
root2 = fabs(S[Root2].Parent);
if( root1 >= root2 )
{
S[Root2].Parent = Root1;
S[Root1].Parent = S[Root1].Parent - 1;
}
else
{
S[Root1].Parent = Root2;
S[Root2].Parent = S[Root2].Parent - 1;
}
}
}

int main()
{
//读入节点数
int N;

//freopen("test.txt","r",stdin);//debug

scanf("%d",&N);
CreateSetType(N);
//看操作
char operation[10];
int a,b;
while(scanf("%s",operation) == 1)//还有数据输入就循环
{
if(strcmp(operation,"S")==0)break;//结束了,判断有几个集合
if(strcmp(operation,"C")==0)
{
scanf("%d %d",&a,&b);
if((Find(H,a)==Find(H,b)) && (Find(H,a) != -1))//根节点相同说明在一根树上
{
printf("yes\n");
}
else
{
printf("no\n");
}
}
if(strcmp(operation,"I")==0)
{
scanf("%d %d",&a,&b);
Union(H,a,b);
}

}

int num = 0;//统计树的个数
for(int i = 0; i < N; i++)
{
if(H[i].Parent < 0)
{
num++;
}
}
if(num==1)
{
printf("The network is connected.\n");
}
else
{
printf("There are %d components.\n",num);
}

return 0;
}


下面这个进行了路径压缩

#include<stdio.h>
#include<string.h>
#include<math.h>

#define MAXN 10001
#define MINH -1
#define ElementType int

typedef struct{
ElementType Data;
float Parent;
}SetType;

SetType H[MAXN];//建立堆

void CreateSetType(int N)
{

for(int i = 0; i < N; i++)
{
H[i].Data = i+1;
H[i].Parent = -1;

}

}

int Find(SetType S[],ElementType X)
{
//在数组S中查找值为X的元素所属的集合
//MAXN为全局变量,为数组S的最大长度
int root;
root = X - 1;
while(S[root].Parent >= 0)
{
root = S[root].Parent;
}
return root;
}

void Union(SetType S[], ElementType X1,ElementType X2)
{
int Root1,Root2;
Root1 = Find(S,X1);
Root2 = Find(S,X2);

if( Root1 != Root2 )
{
int root1,root2;
root1 = fabs(S[Root1].Parent);
root2 = fabs(S[Root2].Parent);
if( root1 >= root2 )
{
S[Root2].Parent = Root1;
S[Root1].Parent = S[Root1].Parent - 1;
}
else
{
S[Root1].Parent = Root2;
S[Root2].Parent = S[Root2].Parent - 1;
}
}
}

int main()
{
//读入节点数
int N;

//freopen("test.txt","r",stdin);//debug

scanf("%d",&N);
CreateSetType(N);
//看操作
char operation[10];
int a,b;
while(scanf("%s",operation) == 1)//还有数据输入就循环
{
if(strcmp(operation,"S")==0)break;//结束了,判断有几个集合
if(strcmp(operation,"C")==0)
{
scanf("%d %d",&a,&b);
if((Find(H,a)==Find(H,b)) && (Find(H,a) != -1))//根节点相同说明在一根树上
{
printf("yes\n");
}
else
{
printf("no\n");
}
}
if(strcmp(operation,"I")==0)
{
scanf("%d %d",&a,&b);
Union(H,a,b);
}

}

int num = 0;//统计树的个数
for(int i = 0; i < N; i++)
{
if(H[i].Parent < 0)
{
num++;
}
}
if(num==1)
{
printf("The network is connected.\n");
}
else
{
printf("There are %d components.\n",num);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: