1.本周学习总结(0--2分)

1.1思维导图

1.2谈谈你对图结构的认识及学习体会。

图结构,它不再像线性表和树结构那样数据之间存在一对一或一对多的关系,它是数据的多对多的一种表现,在用代码表示上,它可以用邻接表和邻接矩阵来写:邻接矩阵,感觉就是二维数组,书本运用了用了两个结构体,一个是顶点的类型,而另一个是完整的图邻接矩阵类型;而邻接表就是不同于邻接矩阵关于图的另外一种表示,书本上运用了三种结构体,也在结构体中运用了一个结构体指针,相较于邻接表来说较难理解,这三个结构体一个用来存放头节点,一个用来存放后续结点,而剩下的就是存放完整的图邻接表。这两种表示存储结构各有各的特点,关于图的遍历分为深度与广度,深度遍历和广度遍历一个运用在图中唯一一次的遍历,一个运用了队列,比起后面的生成树与最短路径简单一些,而生成树可以由普里姆算法和克鲁斯卡尔算法来实现,普里姆算法与贪心算法相类似,只不过还用了一个数组来存放候选边,而克鲁斯卡尔算法则是将最短路径先选出来,然后再连起来。对于这两种算法,看一下还是勉强能懂的,但要写肯定写不出来。

2.PTA实验作业(6分)

2.1.题目1:7-1 图着色问题

2.1.1设计思路

宏定义数组visited并将初值置为0,定义数组d来储存路径;
宏定义二维数组a[501][501]来存储图的边 
void dfs(int i)
       定义 j;
       d[k++]=i;
       标记结点已遍历; 
       for j=1 to v do       
           if 存在边 且 结点未被访问 then 
		       dfs(j);
           end if
       end for
void dfs1()
    定义 i;
    for i=1 to v
        if 结点未被访问 then
             dfs(i); 
    end for


int main()
    输入v、e、z;
    输入存在的边,并在二维将二维矩阵置为1;1 
    调用dfs1函数; 
    输入n;
    while n--
     初始化 b[501]={0},c[501],e[501],sum=0,flag=1;
     for i=1 to v;i++)
        输入c[i];
        b[c[i]]++;
        if b[c[i]]等于1 then sum++;
     end for 
     if sum不等于z then 
	    flag=0;
     end if
     for i=0 to k do 
	    e[i]=c[d[i]];
     end for
     for i=0 to k
        forj=0 to k     
        if a[d[i]][d[j]]等于1并且e[i]等于e[j] then
            flag=0;
            break;
        end if
        if flag等于0 then break;
     end for 
     if flag等于0 then 
	    输出No
	 end if
     else 
	    输出Yes
    end 
    return 0

2.1.2代码截图


2.1.3本题PTA提交列表说明。


1.老师上课讲过要用深度遍历来写,然后看完课本后来写这道题,多加了一个递归口,导致程序没有完全执行完就停止了;
2.写完深度遍历的那一部分,没有完全懂这道题的思路,然后上网查了一下,理解了一遍来写,还是有一些小细节没做好。

2.2 题目2:7-3 六度空间

2.2.1设计思路

宏定义visit数组存放被访问过的结点 
宏定义二维数组arr来存放边的信息 
int BFS(int v)                  //先使用广度遍历,然后记录在范围在六个之间的结点个数 
	新建整型队列q; 
    定义level存放结点距离, 定义tail存放与需要访问结点相关的结点, 定义last暂时存放需要遍历的结点, 定义count存放相关结点个数;
	需要访问的结点入队;
	标记结点已经被访问; 
	while 队列不空 do 
		取队尾元素; 
		出队; 
		for i=1 to N do 
			if  两个结点之间存在边 且 第二个顶点没被访问过 then
				相关结点个数加一; 
				tail = i;
				标记结点已经被访问; 
				出队; 
			end if 
		if temp == last then 
			level++;             //结点距离加一 
			last = tail;         //last下移到下一个相关结点 
		end if
		if level == 6 then break;//如果结点距离超过六,退出循环 
    end 
	return count;
int main() 
	输入N,M; 
	输入邻接表信息; 
	for i=0 to N then
	    使用BFS函数计算;
	    初始化visit数组; 
		输出; 
    return 0;

2.2.2代码截图


2.2.3本题PTA提交列表说明。


1.老师上课讲到这道题时,讲到要用上广度遍历,自己敲的时候,还是把广度遍历的算法敲错了,导致程序运行不来;
2.后面思考怎么统计结点个数时,想到用数组来记录个数,但是退出程序时的那个条件出错了,导致输出的结点只到8,9,后面改了循环条件,发现还是没有完全输出,又看了看建图函数,发现里面的循环条件出错了,导致间的图不完全。
3.输出是不知道c++如何精确到小数点后两位,后来百度了一下,可以用etiosflags(ios::fixed) << setprecision(2) 来写。

2.3 题目3:7-4 公路村村通

2.3.1设计思路

宏定义Minimum无穷大 
宏定义二维数组Map存放边的信息 
宏定义visit数组存放被访问过的结点 
宏定义lowcos存储每个顶点与之相连边的权值
int prim()
    int i,j,k;
    int sum =0,flag=0;
    标记结点已经被访问; 
    权值初始化
    for i=2 to n do
        Min  = Minimum;
        for j=1 to n then             //寻找每个顶点与之相连的边的最小权值
            if !visit[j]&&lowcost[j]<Min then
                Min = lowcost[j];
                k=j;
        end for
        if Min==Minimum then           //如果某个顶点与之相连的边找不到最小权值,则表示道路不通
            flag = 1;
            break;
        sum+=Min;
        标记结点已经被访问;
        for j=1 to n do                   //纠正权值 
            if !visit[j]&&lowcost[j]>Map[j][k] then 
                lowcost[j]=Map[j][k];
    if flag==0                             //存在公路 
        输出sum; 
    else
        输出-1; 
int main()
    while cin>>n>>m do
	    为map与visit置初值; 
        初始化map
        调用prim函数 
    return 0;

2.3.2代码截图


2.3.3本题PTA提交列表说明。


1.不知道无法畅通的情况怎么处理,后来又定义了一个无穷大的变量与最小的路径进行标胶,如果最小的路径等于无穷大,则说明没有路径即无法正常畅通。
2.这道题是使用prim来写,当时还是在没有完全掌握prim算法上来写,没把候选边的那一部分写上去。

3、上机考试错题及处理办法

3.1.

题目:
6-1 jmu-ds-最短路径

错误代码:

错的原因:
由于pta上的图的作业集没有这道题,然后就没认真看,当时写这道题的时候完全是按照老师讲课时的印象写的,和根据自己印象中的prim算法写的,结果当然是错的。考完后又看了看书本,按照理解再敲了一遍。
处理方法:

3.2

题目:
7-2 公路村村通
错误代码:
![](https

错的原因:
这道题是根据舍友提供的思路来敲的,后来百度了这一道题,发现自己在处理prim算法时发现时间复杂度过大,导致答案输不出来。
处理方法:

3.3

7.3
在考试时还没来得及做


#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
const int maxn = 503;
int n,m,s,en;
bool vis[maxn];
int dis[maxn];
int pre[maxn];
int cnt[maxn];
struct node
{
    int v,c,di;
    node()
    {
        v = c = di = 0;
    }
    node(int a,int b)
    {
        v = a;
        c = b;
        di = 0;
    }
    node(int a,int b,int cc)
    {
        v = a;
        c = b;
        di = cc;
    }
    bool operator<(const node &a)const
    {
        return c>a.c;
    }
};
vector<node>vec1[maxn];//dis
vector<node>vec2[maxn];//time
priority_queue<node> que;
void addEdge1(int u,int v,int w,int x)
{
    vec1[u].push_back(node(v,w,x));
}
void addEdge2(int u,int v,int w,int x)
{
    vec2[u].push_back(node(v,w,x));
}
void dijkstra2()
{
    for(int i=0; i<n; i++)
        pre[i] = i;
    memset(vis,false,sizeof(vis));
    for(int i=0; i<=n; i++)
    {
        dis[i] = INF;
        cnt[i] = 0;
    }
    while(!que.empty())
        que.pop();
    dis[s] = 0;
    pre[s] = -1;
    cnt[s] = 0;
    que.push(node(s,0));
    node tmp;
    while(!que.empty())
    {
        tmp = que.top();
        que.pop();
        int u = tmp.v;
        if(vis[u])continue;
        vis[u] = true;
        int l = vec2[u].size();
        for(int i=0; i<l; i++)
        {
            int v = vec2[u][i].v;
            int cost = vec2[u][i].c;
            int juli = vec2[u][i].di;
            if(!vis[v] && dis[v] > dis[u]+cost)
            {
                cnt[v] = cnt[u]+juli;
                dis[v] = dis[u] + cost;
                pre[v] = u;
                que.push(node(v,dis[v]));
            }
            else if(!vis[v] && dis[v] == dis[u]+cost)
            {
                if(cnt[v] > cnt[u] + juli)
                {
                    pre[v] = u;
                    cnt[v] = cnt[u]+juli;
                }
            }
        }
    }
}
void dijkstra1()
{
    for(int i=0; i<n; i++)
        pre[i] = i;
    memset(vis,false,sizeof(vis));
    for(int i=0; i<=n; i++)
        {
            dis[i] = INF;
            cnt[i] = INF;
        }
    while(!que.empty())
        que.pop();
 
 
    dis[s] = 0;
    pre[s] = -1;
    cnt[s] = 1;
    que.push(node(s,0));
    node tmp;
    while(!que.empty())
    {
        tmp = que.top();
        que.pop();
        int u = tmp.v;
        if(vis[u])continue;
        vis[u] = true;
        int l = vec1[u].size();
        for(int i=0; i<l; i++)
        {
            int v = vec1[u][i].v;
            int cost = vec1[u][i].c;
            if(!vis[v] && dis[v] > dis[u]+cost)
            {
                cnt[v] = cnt[u]+1;
                dis[v] = dis[u] + cost;
                pre[v] = u;
                que.push(node(v,dis[v]));
            }
            else if(!vis[v] && dis[v] == dis[u]+cost)
            {
                if(cnt[v] > cnt[u] +1)
                {
                    pre[v] = u;
                    cnt[v] = cnt[u]+1;
                }
            }
        }
    }
}
bool panduan(int s1[],int s2[],int a,int b)
{
    if(a != b)
        return false;
    for(int i=0; i<a; i++)
    {
        if(s1[i] != s2[i])
            return false;
    }
    return true;
}
int main()
{
    //freopen("in.txt","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    //freopen("in.txt","r",stdin);
    cin>>n>>m;
    int a,b,c,d,e;
    for(int i=0; i<m; i++)
    {
        cin>>a>>b>>c>>d>>e;
        if(c == 0)
        {
            addEdge1(b,a,d,e);
            addEdge2(b,a,e,d);
        }
        addEdge1(a,b,d,e);
        addEdge2(a,b,e,d);
    }
//    for(int i=0;i<vec1[3].size();i++)
//        cout<<"is : "<<vec1[3][i].c<<" ";
    cin>>s>>en;
    dijkstra2();
    int ss1[maxn];
    int ss2[maxn];
    int now = en;
    int pos1 = 0,pos2 = 0;
    int dis1 = dis[en];
    while(pre[now] != -1)
    {
        ss1[pos1++] = now;
        now = pre[now];
    }
    dijkstra1();
    now = en;
    while(pre[now] != -1)
    {
        ss2[pos2++] = now;
        now = pre[now];
    }
 
 
    if(panduan(ss1,ss2,pos1,pos2))
    {
        cout<<"Time = "<<dis1<<"; ";
        cout<<"Distance = "<<dis[en]<<": ";
        cout<<s;
        for(int i=pos2-1; i>=0; i--)
            cout<<" => "<<ss2[i];
        cout<<endl;
        return 0;
    }
    cout<<"Time = "<<dis1<<": ";
    cout<<s;
    for(int i=pos1-1; i>=0; i--)
        cout<<" => "<<ss1[i];
    cout<<endl;
    cout<<"Distance = "<<dis[en]<<": ";
    cout<<s;
    for(int i=pos2-1; i>=0; i--)
        cout<<" => "<<ss2[i];
    cout<<endl;
    return 0;
}