3月20日OJ刷题

基于邻接表的新顶点的增加

描述

给定一个无向图,在此无向图中增加一个新顶点。

输入

多组数据,每组m+2行。第一行有两个数字n和m,代表有n个顶点和m条边。顶点编号为1到n。第二行到第m+1行每行有两个数字h和k,代表边依附的两个顶点。第m+2行有一个数字f,代表新插入的顶点编号。当n和m都等于0时,输入结束

输出

每组数据输出n+1行。为增加顶点后的邻接表。每两个数字之间用空格隔开。

输入样例 1 

3 2
1 2
2 3
4
2 1
1 2
4
0 0

输出样例 1

1 2
2 3 1
3 2
4
1 2
2 1
4
#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *next;
}LNode,*LinkList;

typedef struct
{
    int vexnum;
    int edgenum;
    LinkList v[100];
}Graph;

void Create(Graph &g,int n,int m)
{
    g.vexnum=n;
    g.edgenum=m;
    for(int i=1;i<=n;i++)
    {
        g.v[i]=new LNode;
        g.v[i]->data=i;
        g.v[i]->next=NULL;
    }
    for(int i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        LNode *p=new LNode;
        p->data=y;
        p->next=g.v[x]->next;
        g.v[x]->next=p;
        LNode *q=new LNode;
        q->data=x;
        q->next=g.v[y]->next;
        g.v[y]->next=q;
    }
}

void Insert(Graph &g,int x)
{
    g.vexnum=g.vexnum+1;
    g.v[g.vexnum]=new LNode;
    g.v[g.vexnum]->data=x;
    g.v[g.vexnum]->next=NULL;
}
void Print(Graph g)
{
    for(int i=1;i<=g.vexnum;i++)
    {
        LNode *p=g.v[i];
        while(p->next)
        {
            cout<<p->data<<" ";
            p=p->next;
        }
        cout<<p->data<<endl;
    }
}

int main()
{
    int n,m;
    while(cin>>n>>m&&n!=0&&m!=0)
    {
        Graph g;
        Create(g,n,m);
        int x;
        cin>>x;
        Insert(g,x);
        Print(g);
    }
}

基于邻接表的顶点的删除

描述

给定一个无向图,在此无向图中删除一个顶点。

输入

多组数据,每组m+2行。第一行有两个数字n和m,代表有n个顶点和m条边。顶点编号为1到n。第二行到第m+1行每行有两个数字h和k,代表边依附的两个顶点。第m+2行有一个数字f,代表删除的顶点编号。当n和m都等于0时,输入结束。

输出

每组数据输出n-1行。为删除顶点后的邻接表。每两个数字之间用空格隔开。

输入样例 1 

3 2
1 2
2 3
1
2 1
1 2
2
0 0

输出样例 1

2 3
3 2
1

#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *next;
}LNode,*LinkList;

typedef struct
{
    int vexnum;
    int edgenum;
    LinkList v[100];
}Graph;

void Create(Graph &g,int n,int m)
{
    g.vexnum=n;
    g.edgenum=m;
    for(int i=1;i<=n;i++)
    {
        g.v[i]=new LNode;
        g.v[i]->data=i;
        g.v[i]->next=NULL;
    }
    for(int i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        LNode *p=new LNode;
        p->data=y;
        p->next=g.v[x]->next;
        g.v[x]->next=p;
        LNode *q=new LNode;
        q->data=x;
        q->next=g.v[y]->next;
        g.v[y]->next=q;
    }
}

void Delete(Graph &g,int x)
{
    for(int i=1;i<=g.vexnum;i++)
    {
        LNode *p=g.v[i];
        while(p->next)
        {
            if(p->next->data==x)
            {
                p->next=p->next->next;
                break;
            }
            p=p->next;
        }
    }
   for(int i=x;i<g.vexnum;i++)
   {
       g.v[i]=g.v[i+1];
   }
   g.vexnum=g.vexnum-1;
}
void Print(Graph g)
{
    for(int i=1;i<=g.vexnum;i++)
    {
        LNode *p=g.v[i];
        while(p->next)
        {
            cout<<p->data<<" ";
            p=p->next;
        }
        cout<<p->data<<endl;
    }
}

int main()
{
    int n,m;
    while(cin>>n>>m&&n!=0&&m!=0)
    {
        Graph g;
        Create(g,n,m);
        int x;
        cin>>x;
        Delete(g,x);
        Print(g);
    }
}

基于邻接表的新边的增加

描述

给定一个无向图,在此无向图中增加一条边。

输入

多组数据,每组m+2行。第一行有两个数字n和m,代表有n个顶点和m条边。顶点编号为1到n。第二行到第m+1行每行有两个数字h和k,代表边依附的两个顶点。第m+2行有两个数字f和g,代表增加的边所依附的两个顶点。当n和m都等于0时,输入结束。

输出

每组数据输出n行。为增加边后的邻接表。每两个数字之间用空格隔开。

输入样例 1 

3 2
1 2
2 3
3 1
3 1
1 2
1 3
0 0

输出样例 1

1 3 2
2 3 1
3 1 2
1 3 2
2 1
3 1

#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *next;
}LNode,*LinkList;

typedef struct
{
    int vexnum;
    int edgenum;
    LinkList v[100];
}Graph;

void Create(Graph &g,int n,int m)
{
    g.vexnum=n;
    g.edgenum=m;
    for(int i=1;i<=n;i++)
    {
        g.v[i]=new LNode;
        g.v[i]->data=i;
        g.v[i]->next=NULL;
    }
    for(int i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        LNode *p=new LNode;
        p->data=y;
        p->next=g.v[x]->next;
        g.v[x]->next=p;
        LNode *q=new LNode;
        q->data=x;
        q->next=g.v[y]->next;
        g.v[y]->next=q;
    }
}

void Insert(Graph &g,int x,int y)
{
    LNode *p=new LNode;
    p->data=y;
    p->next=g.v[x]->next;
    g.v[x]->next=p;
    LNode *q=new LNode;
    q->data=x;
    q->next=g.v[y]->next;
    g.v[y]->next=q;
}
void Print(Graph g)
{
    for(int i=1;i<=g.vexnum;i++)
    {
        LNode *p=g.v[i];
        while(p->next)
        {
            cout<<p->data<<" ";
            p=p->next;
        }
        cout<<p->data<<endl;
    }
}

int main()
{
    int n,m;
    while(cin>>n>>m&&n!=0&&m!=0)
    {
        Graph g;
        Create(g,n,m);
        int x,y;
        cin>>x>>y;
        Insert(g,x,y);
        Print(g);
    }
}

基于邻接表的边的删除

描述

给定一个无向图,在此无向图中删除一条边。

输入

多组数据,每组m+2行。第一行有两个数字n和m,代表有n个顶点和m条边。顶点编号为1到n。第二行到第m+1行每行有两个数字h和k,代表边依附的两个顶点。第m+2行有两个数字f和g,代表删除的边所依附的两个顶点。当n和m都等于0时,输入结束。

输出

每组数据输出n行。为删除边后的邻接表。每两个数字之间用空格隔开。

输入样例 1 

3 2
1 2
2 3
3 2
3 1
1 2
1 2
0 0

输出样例 1

1 2
2 1
3
1
2
3

#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *next;
}LNode,*LinkList;

typedef struct
{
    int vexnum;
    int edgenum;
    LinkList v[100];
}Graph;

void Create(Graph &g,int n,int m)
{
    g.vexnum=n;
    g.edgenum=m;
    for(int i=1;i<=n;i++)
    {
        g.v[i]=new LNode;
        g.v[i]->data=i;
        g.v[i]->next=NULL;
    }
    for(int i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        LNode *p=new LNode;
        p->data=y;
        p->next=g.v[x]->next;
        g.v[x]->next=p;
        LNode *q=new LNode;
        q->data=x;
        q->next=g.v[y]->next;
        g.v[y]->next=q;
    }
}

void Delete(Graph &g,int x,int y)
{
    LNode *p=g.v[x];
    while(p->next)
    {
        if(p->next->data==y)
        {
            p->next=p->next->next;
            break;
        }
        p=p->next;
    }
    LNode *q=g.v[y];
    while(q->next)
    {
        if(q->next->data==x)
        {
            q->next=q->next->next;
            break;
        }
        q=q->next;
    }
}
void Print(Graph g)
{
    for(int i=1;i<=g.vexnum;i++)
    {
        LNode *p=g.v[i];
        while(p->next)
        {
            cout<<p->data<<" ";
            p=p->next;
        }
        cout<<p->data<<endl;
    }
}

int main()
{
    int n,m;
    while(cin>>n>>m&&n!=0&&m!=0)
    {
        Graph g;
        Create(g,n,m);
        int x,y;
        cin>>x>>y;
        Delete(g,x,y);
        Print(g);
    }
}

基于邻接表的深度优先遍历

描述

一个连通图采用邻接表作为存储结构。设计一个算法,实现从顶点v出发的深度优先遍历的非递归过程。

输入

多组数据,每组m+2数据行。第一行有两个数字n和m,代表有n个顶点和m条边。顶点编号为1到n。第二行到第m+1行每行有两个整数h和k,代表边依附的两个顶点。第m+2行有一个整数d,代表从d开始遍历。当n和m都等于0时,输入结束。

输出

每组数据输出一行,为深度优先搜索的遍历结果。每两个数字之间用空格隔开。

输入样例 1 

3 2
1 2
1 3
1
2 1
1 2
2
0 0

输出样例 1

1 2 3
2 1

#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *next;
}LNode,*LinkList;

typedef struct
{
    int vexnum;
    int edgenum;
    LinkList v[100];
}Graph;

void Create(Graph &g,int n,int m)
{
    g.vexnum=n;
    g.edgenum=m;
    for(int i=1;i<=n;i++)
    {
        g.v[i]=new LNode;
        g.v[i]->data=i;
        g.v[i]->next=NULL;
    }
    for(int i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        LNode *p=new LNode;
        p->data=y;
        p->next=g.v[x]->next;
        g.v[x]->next=p;
        LNode *q=new LNode;
        q->data=x;
        q->next=g.v[y]->next;
        g.v[y]->next=q;
    }
}

void DFS(Graph &g)
{
    int d,top=0,visit[100],Stack[100];
	for(int i=0;i<100;i++)
		visit[i]=0;
	cin>>d;
	cout<<d;
	Stack[top++]=d;
	visit[d]=1;
	while(top>0)
	{
		int t=-1;
		LinkList p=g.v[Stack[top-1]];
		while(p)
		{
			if(!visit[p->data])
				t=p->data;
			p=p->next;
		}
		if(t==-1)
			top--;
		else
		{
			cout<<" "<<t;
			Stack[top++]=t;
			visit[t]=1;
		}
	}
	cout<<endl;
}
void Print(Graph g)
{
    for(int i=1;i<=g.vexnum;i++)
    {
        LNode *p=g.v[i];
        while(p->next)
        {
            cout<<p->data<<" ";
            p=p->next;
        }
        cout<<p->data<<endl;
    }
}

int main()
{
    int n,m;
    while(cin>>n>>m&&n!=0&&m!=0)
    {
        Graph g;
        Create(g,n,m);
        DFS(g);
    }
}

最长的最短路径的求解

描述

设计一个算法,求图G中距离顶点v的最短路径长度最大的一个顶点。

输入

多组数据,每组数据m+2行。每组数据第一行为两个整数n和m,代表有n个顶点m条路。顶点编号为1到n。第二行到第m+1行每行有三个整数a,b和c,代表顶点a和顶点b之间有一条长度为c的路。第m+2有一个整数v,代表顶点v。当n和m都等于0时,输入结束。

输出

每组数据输出两行。第一行为最短路径最长的顶点编号c,第二行为两点的最短距离d。

输入样例 1 

4 4
1 2 1
2 3 1
3 4 1
2 4 1
4
4 3
1 2 3
2 3 2
2 4 6
3
0 0

输出样例 1

1
2
4
8

 

#include<bits/stdc++.h>
using namespace std;
int n,m;
int edge[200][200];
int dis[200];
int visit[200];
void Dijkstra(int s)
{
    for(int i=1;i<=n;i++)
    {
        dis[i]=edge[s][i];
        visit[i]=0;
    }
    dis[s]=0;
    visit[s]=1;
    int minn,k;
    for(int i=0;i<n-1;i++)
    {
        minn=9999;
        for(int i=1;i<=n;i++)
        {
            if(!visit[i]&&dis[i]<minn)
            {
                minn=dis[i];
                k=i;
            }
        }
        visit[k]=1;
        for(int i=1;i<=n;i++)
        {
            if(!visit[i]&&dis[i]>dis[k]+edge[k][i])
            {
                dis[i]=dis[k]+edge[k][i];
            }
        }
    }
}
int main()
{
    while(cin>>n>>m&&n!=0&&m!=0)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                edge[i][j]=9999;
            }
        }
        int x,y,d;
        for(int i=0;i<m;i++)
        {
            cin>>x>>y>>d;
            edge[x][y]=d;
            edge[y][x]=d;
        }
        int s;
        cin>>s;
        Dijkstra(s);
        int ans,maxx=-1;
		for(int i=1;i<=n;i++)
		{
			if(dis[i]>maxx&&dis[i]<9999)
			{
				maxx=dis[i];
				ans=i;
			}
		}
		cout<<ans<<endl;
		cout<<maxx<<endl;
    }
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值