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\n",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\n",pur[n]);
47     }
48     return 0;
49 }
View Code

 

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

posted @ 2015-12-30 22:54  zhaop  阅读(212)  评论(0编辑  收藏  举报