图总结

图总结

1.思维导图

2.重要概念的笔记

(graph)是一种网状数据结构,图是由非空的顶点集合和一个描述顶点之间关系的集合组成。

图由顶点和边组成,顶点表示对象,,边表示两个对象间的连接关系。

顶点的度: 连接顶点的边的数量称为该顶点的度。顶点的度在有向图和无向图中具有不同的表示。对于无向图,一个顶点V的度比较简单,其是连接该顶点的边的数量,记为D(V)。

连通图:在无向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该无向图为连通图。

强连通图:在有向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该有向图为强连通图。

连通网:在连通图中,若图的边具有一定的意义,每一条边都对应着一个数,称为权;权代表着连接连个顶点的代价,称这种连通图叫做连通网。

生成树:一个连通图的生成树是指一个连通子图,它含有图中全部n个顶点,但只有足以构成一棵树的n-1条边。一颗有n个顶点的生成树有且仅有n-1条边,如果生成树中再添加一条边,则必定成环。

最小生成树:在连通网的所有生成树中,所有边的代价和最小的生成树,称为最小生成树。

Prim算法:

Kruskal算法(起点到终点最短距离):

最短路径问题是指:如果从图中某一顶点(源点)到达另一顶点(终点)的路径可能不止一条,如何找到一条路径使得沿此路径上各边的权值总和(称为路径长度)达到最小。

关键路径通常(但并非总是)是决定项目工期的进度活动序列。它是项目中最长的路径。

Dijkstra(迪杰斯特拉)算法:

Floyd算法(每一对顶点间最短距离):

3.疑难问题及解决方案

1.对关键路径与最短路径无法区分

通过查阅资料

最短路径:如果从某顶点出发,这个顶点称为源点,经图的边到达另一顶点,这个顶点称为终点,所经过的路径不止一条,找出一条路径使的沿此路径上各边的权值之和为最小。(从源点到终点走得最短的路线权值之和)(默认为1)

关键路径:采用边表示活动网络,简称AOE网络。每个顶点代表一个事件,事件说明某些活动或某一项活动的完成,边表示活动,权表示活动持续的时间(关键路径法,也称为统筹方法)。(从源点到汇点完成时间最长路径之和
图着色问题

图着色问题是一个著名的NP完全问题。给定无向图G=(V,E),问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色?

但本题并不是要你解决这个着色问题,而是对给定的一种颜色分配,请你判断这是否是图着色问题的一个解。

输入格式
输入在第一行给出3个整数V(0<V≤500)、E(≥0)和K(0<K≤V),分别是无向图的顶点数、边数、以及颜色数。顶点和颜色都从1到V编号。随后E行,每行给出一条边的两个端点的编号。在图的信息给出之后,给出了一个正整数N(≤20),是待检查的颜色分配方案的个数。随后N行,每行顺次给出V个顶点的颜色(第i个数字表示第i个顶点的颜色),数字间以空格分隔。题目保证给定的无向图是合法的(即不存在自回路和重边)。

输出格式
对每种颜色分配方案,如果是图着色问题的一个解则输出Yes,否则输出No,每句占一行。

思路:从第1个节点开始扫描,第1个节点颜色为1,第i个节点欲试探的颜色为color(color从1开始),循环判断i与已着色的前i-1个节点是否相邻,如果相邻且颜色也相同,那么颜色color则不合适,立刻跳出循环,下一个试探的颜色为++color,并且重新开始循环判断,试探下一个颜色是否合适。如果i与前i-1个节点循环判断后没有既相邻又同颜色的,那么第i个节点颜色为当前的color。但是如果color到4都没有符合条件,那么我们就需要重新对i-1节点重新着色(回溯),它的颜色应该+1,并且继续循环判断i-1节点。

代码如下:

#include<iostream>
#include<memory.h>
using namespace std;
struct Graph
{
	int a[501][501];
	int v,e;
};
int z,visited[501]={0},d[501],k=0,n,i,j;
Graph *creat()
{
	Graph *g=new Graph;
	int x,y,i;
	memset(g->a,0,sizeof(g->a));
	cin>>g->v>>g->e>>z;
	for(i=0;i<g->e;i++)
	{
		cin>>x>>y;
		g->a[x][y]=g->a[y][x]=1;
	}
	return g;
}
void dfs(Graph *g,int i)
{
	int j;
	d[k++]=i;
	visited[i]=1;
	for(j=1;j<=g->v;j++)
	{
		if(g->a[i][j]==1 && visited[j]==0) dfs(g,j);
	}
}
void dfs1(Graph *g)
{
	int i;
	for(i=1;i<=g->v;i++)
	{
		if(visited[i]==0) dfs(g,i);
	}
}
int main()
{
	Graph *g=creat();
	dfs1(g);
	cin>>n;
	while(n--)
	{
		int b[501]={0},c[501],e[501],sum=0,flag=1;
		for(i=1;i<=g->v;i++)
		{
			cin>>c[i];
			b[c[i]]++;
			if(b[c[i]]==1) sum++;
		}
		if(sum!=z) flag=0;
		for(i=0;i<k;i++) e[i]=c[d[i]];
		for(i=0;i<k;i++)
		{
			for(j=0;j<k;j++)
			{
				if(g->a[d[i]][d[j]]==1 && e[i]==e[j])
				{
					flag=0;
					break;
				}
			}
			if(flag==0) break;
		}
		if(flag==0) puts("No");
		else puts("Yes");
	}
	return 0;
}
posted @ 2020-05-17 15:38  宋林涛  阅读(181)  评论(0编辑  收藏  举报