• 20151230训练题解(最短路+拓扑排序)


    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=103223#problem/B

    这道题用经典的dijsktra算法,大概思路就是用dist[x]存储x到已经确定集合的最短路,n次循环到这个这个最小值,然后更新其他点到新集合的最短路即对应的dist[]

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <algorithm>
     5 using namespace std;
     6 const int MAX = 105;
     7 const int INF = 0x3f3f3f3f;
     8 int g[MAX][MAX],dist[MAX],vis[MAX];
     9 int n,m;
    10 void dijstra()
    11 {
    12     memset(vis, 0, sizeof(vis));
    13     for(int i = 1; i <= n; i++)
    14     {
    15         if(g[1][i] != INF)
    16             dist[i] = g[1][i];
    17         else
    18             dist[i] = INF;
    19     }
    20     dist[1] = 0;
    21     vis[1] = 1;
    22     int maxn,pos = 1,temp; //pos =1,作为起点
    23     for(int i = 1; i <= n; i++)
    24     {
    25         maxn = INF;
    26         for(int j = 1; j <= n; j++)
    27         {
    28             if(vis[j] == 0 && dist[j] < maxn) //找不到集合的最小距离,mazn
    29             {
    30                 maxn = dist[j];
    31                 temp = j;
    32             }
    33         }
    34         vis[temp] = 1; //把该点加入集合,即设访问为1
    35         pos = temp;
    36         for(int j = 1; j <= n; j++)
    37         {
    38             if(vis[j] == 0)   //跟新以pos为起点到集合的距离
    39                 dist[j] = min(dist[j], dist[pos] + g[pos][j]);
    40         }
    41     }
    42 }
    43 int main()
    44 {
    45    while(scanf("%d%d", &n,&m) != EOF)
    46    {
    47        int a,b,c;
    48        if(n == 0 || m == 0)
    49            break;
    50        memset(g, INF, sizeof(g));
    51        for(int i = 1; i <= m; i++)
    52        {
    53            scanf("%d%d%d", &a,&b,&c);
    54            if(g[a][b] > c)  //考虑重边,去最小
    55                g[a][b] = g[b][a] = c;
    56        }
    57        dijstra();
    58        printf("%d
    ",dist[n]);
    59    }
    60    return 0;
    61 }
    View Code

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=103223#problem/C

    拓扑排序就是通过找入度为0的点,找到后更新其他的点入度,然后在找入度为0的点直到没有为0的点,为了便于理解这里直接用两重循环写的,后期大家熟悉了就可以用栈来存入度为0的点

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 int g[550][550];
     7 int indegree[550]; //存入度
     8 int pur[550];
     9 int main()
    10 {
    11     int n,M,x,y;
    12     while(scanf("%d%d",&n,&M) != EOF)
    13     {
    14         memset(indegree,0,sizeof(indegree));
    15         memset(g,0,sizeof(g));
    16 
    17         for(int i = 1;i <= M; i++)
    18         {
    19            scanf("%d%d",&x,&y);
    20            if(g[x][y] == 0)
    21            {
    22               g[x][y] = 1;
    23               indegree[y]++;
    24            }
    25          }
    26          int k=1;
    27          for(int i = 1; i <= n; i++)
    28          {
    29              for(int j = 1; j <= n; j++)
    30              {
    31                 if(indegree[j] == 0) //找入度为0的点
    32                 {
    33                     pur[k++] = j;
    34                     indegree[j]--;
    35                     for(int m = 1; m <= n; m++) //更新
    36                     {
    37                         if(g[j][m])
    38                             indegree[m]--;
    39                     } 
    40                     break;
    41                 }
    42              }
    43          }
    44          for(int i = 1; i < n; i++)
    45              printf("%d ",pur[i]);
    46          printf("%d
    ",pur[n]);
    47     }
    48     return 0;
    49 }
    View Code

    找第一题没注意到数据类型,最后可能害不少人浪费了不少时间,sorry...图论题目可能大家没看到,应该数据结构大家也都讲了,但是请大家记住,讲了,听懂了,不一定是真的会,只有AC才是王道!

  • 相关阅读:
    在windows使用gvim的感受
    javascript数据结构之单链表
    javascript数据结构之顺序表
    用javascript来判别回文数
    javascript数据结构之队列
    javascript数据结构之栈
    转载像元素周期表一样的html5的标签图集
    转载一篇比较详细的讲解html,css的一篇文章,很长
    CSS简单选择器的学习笔记
    学习Javascript的编程风格
  • 原文地址:https://www.cnblogs.com/zhaopAC/p/5090304.html
Copyright © 2020-2023  润新知