图总结
图总结
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;
}