【思维导图】

【学习总结】

  • 深度遍历算法、广度遍历算法:容易理解,便于找寻,比较基础
  • 拓扑排序算法:并不一定唯一,要有向图以及判断有没有环路
    • Prim和Kruscal算法:都是从连通图中找出最小生成树的算法。Prim算法直接查找,多次寻找邻边的权重最小值,而Kruskal是需要先对权重排序后查找的,则Kruskal算法效率比Prim快。
    • Dijkstra算法:使用了广度优先搜索解决赋权有向图最短路径问题,以起始点为中心向外层层扩展,直到扩展到终点为止,最终得到一个最短路径

 

 

【设计思路】直接用图的遍历,遍历的时候判断是否颜色相等即可。 
注意需要不同颜色的个数需要等于k。

【代码截图】

 

 【提交列表】

 

 【测试点】

 【错误改正】

先开始在遍历的时候没有在二维数组中的序列搞对,循环时出现错误,遍历不完全;

后来发现还是在数组的循环遍历时出现问题,改正后答案正确;

 

 

【提交列表】

 

 

【代码截图】

 

 

【测试点】

【错误改正】

这个题是从网上找的,网上给的思路是

edge数组的作用记录两点间边的权值,默认的是所有点中 到点v最小的边值几位edge[v]

book数组的作用是记录某点x是否进入了树中,记录了标记为1,没进入的话标记为0;

每当找到一个点,就不断更新edge数组的边值;

错误我自己也没看懂还。

 

【代码思路】

算法思路:使用并查集

                  1、把具有朋友关系的人(两个人之间是朋友关系,或、有共同的朋友(只要有共同的朋友且两个人不是朋友,不管这两个人是不是敌人))放在一个集合里面。例如:{a,b,c,d,e},{f,g,h},其中abcde和fgh都不是朋友或者没有共同朋友。具体做法:First:将每一个人作为一个集合

                                    Second:使用WeightedUnion(使用加权规则得到改进的Union操作)把具有朋友关系的人放在同一个集合里。

2、用二维数组bad存储敌对关系。

说明:如果b,c的共同朋友是a,但b,c是敌对关系则abc的集合为{a->{b,c}}(想象一下树中a为根节点,b,c为a的子女节点……)

判断:情况一:a,b在同一个集合中,且bad[a][b]=1

           情况二:a,b不在同一个集合中,且bad[a][b]=1

   情况三:a,b在同一个集合中,且bad[a][b]=-1

           情况四:a,b在不在同一个集合中,且bad[a][b]=-1;

 

【代码截图】

【提交列表】

【测试点】

【错误改正】

在这种遍历中我经常会发生顺序的错误,便利时数组的序号搞错,到最后遍历时不完全;

网上的代码写的很详细,有自己理解过。

 

【最后排名】

 

 

 

【阅读代码】

 

  1. #include <iostream>  
  2. #include <cstdio>  
  3. #include <algorithm>  
  4. #include <cstring>  
  5. using namespace std;  
  6. int n, m, s,q;  
  7. int b[600];  
  8. int a[600][600];  
  9. int c[600];  
  10. int pre[600];  
  11. int inf;  
  12. int sx[600];  
  13. int toval[600];  
  14. int main()  
  15. {  
  16.     memset(a, 0, sizeof(0));  
  17.     int pathnum[600];  
  18.     inf=99999999;  
  19.     scanf("%d%d%d%d", &n, &m, &s, &q);  
  20.     int i;  
  21.     int j;  
  22.     for(i=0; i<n; i++)  
  23.         for(j=0; j<n; j++)  
  24.         {  
  25.             if(i==j)a[i][j]=0;  
  26.             else a[i][j]=inf;  
  27.         }  
  28.     for(i=0; i<n; i++)scanf("%d", &b[i]);  
  29.     for(i=0; i<m; i++)  
  30.     {  
  31.         int x, y, z;  
  32.         scanf("%d%d%d", &x, &y, &z);  
  33.         if(z<a[x][y])  a[x][y]=a[y][x]=z;  
  34.     }  
  35.     int vis[600];  
  36.     for(i=0; i<n; i++)  
  37.     {  
  38.         vis[i]=0;  
  39.         c[i]=inf;  
  40.         toval[i]=0;  
  41.     }  
  42.     int k;  
  43.     c[s]=0;  
  44.     vis[s]=1;  
  45.     pathnum[s]=1;  
  46.     toval[s]=b[s];  
  47.     {  
  48.         for(i=0; i<n; i++)  
  49.         {  
  50.             int mini, minn;  
  51.             mini=s;  
  52.             minn=inf;  
  53.             for(j=0; j<n; j++)  
  54.             {  
  55.   
  56.                 if(vis[j]==0 && minn>c[j])  
  57.                 {  
  58.                     mini=j;  
  59.                     minn=c[j];  
  60.                 }  
  61.             }  
  62.             vis[mini]=1;  
  63.             for(j=0; j<n; j++)  
  64.             {  
  65.                 if(vis[j]==0)   if(c[mini]+a[mini][j]<c[j])  
  66.                     {  
  67.                         c[j]=c[mini]+a[mini][j];  
  68.                         pre[j]=mini;  
  69.                         toval[j]=b[j]+toval[mini];  
  70.                         pathnum[j]=pathnum[mini];  
  71.                     }  
  72.                     else if(c[mini]+a[mini][j]==c[j] )  
  73.                     {  
  74.                         if( toval[j]<b[j]+toval[mini])  
  75.                         {  
  76.                             toval[j]=b[j]+toval[mini];  
  77.                             pre[j]=mini;  
  78.                         }  
  79.                         pathnum[j]+=pathnum[mini];  
  80.                     }  
  81.             }  
  82.         }  
  83.     }  
  84.     int top=0;  
  85.     j=q;  
  86.     while(j!=s)  
  87.     {  
  88.         sx[top++]=j;  
  89.         j=pre[j];  
  90.     }  
  91.     sx[top]=j;  
  92.     printf("%d %d\n", pathnum[q], toval[q]);  
  93.     for(; top>=0; top--)  
  94.     {  
  95.         printf("%d", sx[top]);  
  96.         if(top!=0)printf(" ");  
  97.     }  
  98.     return 0;  
  99. }  

 【学习总结】

图这一章中最重要的是对数据的遍历,在制作二维或三维数组是对数据的排列,对数据取出的方式路径的选择;

不同的方法有不同的用数据路径,时间复杂度代码效率都不同,在使用时应该比较各个方面后再使用;

学完图这一章之后,理解了许多储存的结构,和对取出数据的方法的认识。

 

posted on 2018-06-18 19:40  lzlzlzptptpt  阅读(135)  评论(1编辑  收藏  举报

导航