提高题3-1

Problem 3 Graph and Tree (Difficulty index ★★★★☆)

3-1. 

A graph is a set of nodes connected in various ways by edges. You can often start at one node, wander along various edges from node to node, and either wind up back where you started, or just visit several of the other nodes in the graph. Some nodes you may not be able to reach at all. The problem to consider is this: how can you tell if a given graph will let you start on any node and visit every other node in the graph, each by some path of edges?

Graphs which allow you to do this are called "connected" graphs.

For this problem, a graph will be defined by a list of edges.

For example, a graph with nodes {abcde} might be defined as having edges:

(ab)  (ac)  (de)

This means that you can travel from node a to node b along a single edge, froma to c, and from d to e. But you can't get from a to e, so this graph is not connected.  The order of the nodes makes no difference, because for this problem, the edges of the graph have no direction.  

So, write a program that, given a list of nodes like that above, and a list of edges likeabove, in text form, determine whether it is possible to get from each node in the graph to every other.

谷歌翻译:图形是以边缘以各种方式连接的一组节点。你可以经常从一个节点开始,从节点到节点的各个边缘漫游,然后回到你开始的地方,或者访问图中的几个其他节点(注:不回到原来的位置也没关系)。有些节点可能根本无法访问。需要考虑的问题是:你如何知道一个给定的图形是否会让你从任何节点开始,并访问图形中的每个其他节点,每个节点都是通过边缘的路径?
允许您执行此操作的图形称为“连接”图形。
对于此问题,将通过边列表定义图形。
例如,具有节点{abcde}的图可以被定义为具有边:
ab)(ac)(de
这意味着您可以沿着单个边从节点a到节点b行进,从ac,从de。但是你不能从ae,所以这个图没有连接。节点的顺序没有差别,因为对于这个问题,图的边缘没有方向。
所以,编写一个程序,给出一个像上面那样的节点列表,以及文本形式的上述边的列表,确定是否可能从图中的每个节点到达其他节点。


#include <iostream>
#include <string>
#include<iomanip>
using namespace std;
#define Max_num 10
typedef struct MGraph{
string vexs[10];//顶点信息  单行数组,存储abcd等
int arcs[10][10];//邻接矩阵
int vexnum, arcnum;//顶点数和边数
}MGraph;
int LocateVex(MGraph G, string u)//返回顶点u在图中的位置
{
for(int i=0; i<G.vexnum; i++)
if(G.vexs[i]==u)
return i;
return -1;
}
void CreateUDN(MGraph &G)//构造无向网
{
string v1, v2;
int i, j, k;
cout<<"请输入顶点数和边数:";
cin>>G.vexnum>>G.arcnum;


cout<<"请输入顶点:";
for(i=0; i<G.vexnum; i++)
cin>>G.vexs[i];  //在顶点数确定的情况下把数组vexs填满


for(i=0; i<G.vexnum; i++)
for(j=0; j<G.vexnum; j++)
G.arcs[i][j]=0;//初始化权值=0  


cout<<"请输入边:"<<endl;
for(k=0; k<G.arcnum; k++)
{
cin>>v1>>v2;//>>w;
i=LocateVex(G, v1);  //获取v1在单行数组中的位置
j=LocateVex(G, v2);  //获取v2在单行数组中的位置   
G.arcs[i][j]=G.arcs[j][i]=1;  //横行和竖行对应 其实对称 权值为1表明连接
}
}
void Short_Length_floyd(MGraph G,int D[Max_num][Max_num])//弗洛伊德算法
{
int u,v,w,i,j,k=0;
for(u=0;u<G.vexnum;u++)
{
for(v=0;v<G.vexnum;v++)
{
D[u][v]=G.arcs[u][v];//将各边的权值赋给D[u][v]
}
}
for(u=0;u<G.vexnum;u++)
for(v=0;v<G.vexnum;v++)
for(w=0;w<G.vexnum;w++)
{
if(D[v][u]==1&&D[u][w]==1)   //起连接作用,将本可以连起来的2个点确实连起来
{
D[v][w]=1;
}
}
for(i=0;i<G.vexnum;i++)
D[i][i]=0;
for(i=0;i<G.vexnum;i++)
for(j=i;j<G.vexnum;j++)
if(i!=j)
{
if(D[i][j])
cout<<G.vexs[i]<<"能到达"<<G.vexs[j]<<endl;
else
k=1;
}
if(k)
{
cout<<"此图不连接"<<endl;
}
else
{
cout<<"连接"<<endl;
}


}
void main()
{
MGraph g;
int D[Max_num][Max_num];
CreateUDN(g);
Short_Length_floyd(g,D);
system("pause");
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值