要求一个有向图各顶点的入度和出度:
先用一个二维数组Edge存储表示邻接矩阵,输入文件中顶点的序号是从1开始,当输入一条有向边<u, v>时,将Edge[u-1][v-1] = 1就得啦;
第i+1个顶点的出度等于邻接矩阵中第i行所有元素中元素值为1的个数,把第i行所有元素值累加起来,得到的结果也是该顶点的出度,同理,在计算第i+1个顶点的入度时,也只需要将第i列所有元素值累加起来就可以了;
n, m 分别表示有向图的顶点个数和有向边,n = m = 0时处理文件结束; (0 < n, m <= 100)
测试样例:
7 9
1 2
2 3
2 5
2 6
3 5
4 3
5 2
5 4
6 7
0 0
运行结果:
该有向图各顶点的入度分别为:1 3 1 1 2 1 0
该有向图各顶点的出度分别为:0 2 2 1 2 1 1
简单代码如下:(邻接矩阵实现)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define MAXN 105
#define RST(N)memset(N, 0, sizeof(N))
using namespace std;
int n, m, Edge[MAXN][MAXN]; //顶点数,有向边数,邻接矩阵;
int Mc, Md, u, v; //入度,出度,边的起点,终点;
void Init() //初始化;
{
RST(Edge);
for(int i=1; i<=m; i++) { //添加有向边;
scanf("%d %d", &u, &v);
Edge[u-1][v-1] = 1;
}
}
void Print_In_Degree() //输出有向图各顶点的入度;
{
printf("该有向图各顶点的入度分别为:");
for(int i=0; i<n; i++) {
Mc = 0;
for(int j=0; j<n; j++) Mc += Edge[i][j];
printf("%d", Mc);
i == n-1 ? printf("\n") : printf(" ");
}
}
void Print_Out_Degree() //输出有向边各顶点的出度;
{
printf("该有向图各顶点的出度分别为:");
for(int i=0; i<n; i++) {
Md = 0;
for(int j=0; j<n; j++) Md += Edge[j][i];
printf("%d", Md);
i == n-1 ? printf("\n") : printf(" ");
}
}
int main()
{
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
while(~scanf("%d %d", &n, &m) && n || m) {
Init();
Print_In_Degree(), Print_Out_Degree();
}
fclose(stdin);
fclose(stdout);
return 0;
}
邻接表实现:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define MAXN 105
#define RST(N)memset(N, 0, sizeof(N))
using namespace std;
struct ArcNode //边节点;
{
int rvex; //有向边的另一个邻接点的序号;
ArcNode *nextarc; //指向下一个边节点的指针;
};
struct VNode //顶点;
{
int data; //定点信息;
ArcNode *head1; // 出边表的表头指针;
ArcNode *head2; // 入边表的表头指针;
};
struct LGraph //图的邻接表存储结构;
{
VNode vertex[MAXN]; //顶点数组;
int VexNum, ArcNum; //顶点数和边数;
};
int u, v; //有向边的前后顶点;
LGraph Lg; //图;
void Init() //初始化;
{
for(int i=0; i<Lg.VexNum; i++) { //初始化表头指针为空;
Lg.vertex[i].head1 = Lg.vertex[i].head2 = NULL;
}
}
void creatLG() //采用邻接表存储表示,构造有向图G;
{
ArcNode *pi; //用来构造边链表的边节点指针;
for(int i=0; i<Lg.ArcNum; i++) {
scanf("%d %d", &u, &v); //输出一条边的前后节点;
u--, v--;
//将新节点插入出度链表;
pi = new ArcNode; //为pi分配空间(如果有足够空间)
pi->rvex = v;
pi->nextarc = Lg.vertex[u].head1; //插入出边链表;
Lg.vertex[u].head1 = pi;
//将新节点插入入度链表;
pi = new ArcNode;
pi->rvex = u;
pi->nextarc = Lg.vertex[v].head2; //插入入边链表;
Lg.vertex[v].head2 = pi;
}
}
void IN_DEGREE() //输出每个顶点的出度;
{
ArcNode *pi;
for(int i=0; i<Lg.VexNum; i++) {
int res = 0;
pi = Lg.vertex[i].head1;
while(pi != NULL) { //统计各顶点的出度;
res++;
pi = pi->nextarc;
}
printf("%d", res);
printf(i == Lg.VexNum-1 ? "\n" : " ");
}
}
void OUT_DEGREE() //输出每个顶点的入度;
{
ArcNode *pi;
for(int i=0; i<Lg.VexNum; i++) {
int res = 0;
pi = Lg.vertex[i].head2;
while(pi != NULL) { //统计各顶点的入度;
res++;
pi = pi->nextarc;
}
printf("%d", res);
printf(i == Lg.VexNum-1 ? "\n" : " ");
}
}
//释放图G邻接表各顶点的边链表中所有边节点所占的存储空间;
void DeleteLG()
{
ArcNode *pi; //用来指向边链表中各边节点的指针;
for(int i=0; i<Lg.VexNum; i++) {
pi = Lg.vertex[i].head1;
while(pi != NULL) {
Lg.vertex[i].head1 = pi->nextarc;
delete pi; //释放第i个顶点的出边表各边节点所占的空间;
pi = Lg.vertex[i].head1;
}
pi = Lg.vertex[i].head2;
while(pi != NULL) {
Lg.vertex[i].head2 = pi->nextarc;
delete pi; //释放第i个顶点的入边表各边节点所占的空间;
pi = Lg.vertex[i].head2;
}
}
return ;
}
int main()
{
while(~scanf("%d %d", &Lg.VexNum, &Lg.ArcNum) && Lg.VexNum||Lg.ArcNum) {
Init(), creatLG();
IN_DEGREE(), OUT_DEGREE();
DeleteLG();
}
return 0;
}