HDU 1874 SPFA/Dijkstra/Floyd

这题作为模板题,解法好多...

最近周围的人都在搞图论阿,感觉我好辣鸡,只会跟风学习。

暂时只有SPFA和Dijkstra的

SPFA (邻接表版。也可以写成临接矩阵存图,但题目可能给出平行边的,所以要注意找最小的边储存,还要注意判断一个点是否多次进入队列)老实说觉得SPFA好像只是被队列优化过的ford一样的..

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <string.h>
 5 #include <utility>
 6 #include <vector>
 7 #include <queue>
 8 #define MAXX 10010
 9 using namespace std;
10 
11 const int N = 250;
12 const int INF = 0x3f3f3f3f;
13 
14 
15 typedef struct sion
16 {
17     int dis;
18     int nxp;
19 }sion;
20 
21 int dic[N];
22 bool vis[N];
23 vector<sion>li[N];
24 
25 
26 int spfa(int &s, int &t)
27 {
28     queue<int>q;
29     q.push(s);
30     vis[s] = 1;
31     dic[s] = 0;
32     while(!q.empty())
33     {
34         int pre = q.front();
35         q.pop();
36         for(int i = 0; i < li[pre].size(); i++)
37         {
38            // cout << dic[li[pre][i].nxp] << "~";
39             if(dic[li[pre][i].nxp] > dic[pre] + li[pre][i].dis)
40             {
41                 dic[li[pre][i].nxp] = dic[pre] + li[pre][i].dis;
42                     q.push(li[pre][i].nxp);
43                    // cout << dic[li[pre][i].nxp] << "!";
44             }
45         }
46 
47     }
48     return dic[t];
49 }
50 
51 void init()
52 {
53     memset(vis,false,sizeof(vis));
54     memset(dic,INF,sizeof(dic));
55     for(int i = 0; i < N; i++)
56         li[i].clear();
57     return ;
58 }
59 
60 int main()
61 {
62     int n, m;
63     int s, t;
64     while(cin >> n >> m)
65     {
66         init();
67         sion a;
68         int x;
69         for(int i = 0; i < m; i++)
70         {
71             scanf("%d%d%d",&x, &a.nxp, &a.dis);
72             li[x].push_back(a);
73             int temp = a.nxp;
74             a.nxp = x;
75             li[temp].push_back(a);
76         }
77         scanf("%d%d", &s, &t);
78         int y = spfa(s, t);
79         if(y >= INF)
80         {
81             printf("-1\n");
82         }
83         else printf("%d\n", y);
84     }
85 }

 Dijkstra(邻接表版。临接矩阵需要注意的同上) 搞了几个小时,最后WA发现原来是原理没搞清orz,每次从一个点out后,需要找的是未被标记的离起点最小的点,而我找的是队列里离上一个点最小的点,这就有问题了。唉,人蠢没得治

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <string.h>
 5 #include <queue>
 6 #include <utility>
 7 #include <vector>
 8 #define MAXX 1010
 9 #define MMI(x) memset(x, INF, sizeof(x))
10 #define MMF(x) memset(x, false, sizeof(x))
11 using namespace std;
12 
13 const int N = 250;
14 const int INF = 0x3f3f3f3f;
15 
16 typedef struct sion
17 {
18     int dis;
19     int nxp;
20 }sion;
21 
22 vector<sion> edge[MAXX];
23 
24 int dic[N];
25 bool vis[N];
26 
27 void init()
28 {
29     memset(vis,false,sizeof(vis));
30     memset(dic,INF,sizeof(dic));
31     for(int i = 0; i < MAXX; i++)
32     {
33         edge[i].clear();
34     }
35 }
36 void dijkstra(int &s, int &n)
37 {
38     queue<int >q;
39     vis[s] = 1;
40     dic[s] = 0;
41     q.push(s);
42 
43     while(!q.empty())
44     {
45         int mi = INF;
46         int t = q.front();
47         int x = 0;
48         q.pop();
49         for(int i = 0; i < edge[t].size(); i++)
50         {
51             int np = edge[t][i].nxp;
52             int s = dic[t] + edge[t][i].dis;
53 
54             if(dic[np] > s && !vis[np])
55             {
56                 dic[np] = s;
57             }
58         }
59         for(int i = 0; i < n; i ++)
60             if(!vis[i] && mi > dic[i])
61                 mi = dic[i], x = i;
62         if(mi == INF)
63             break;
64         q.push(x);
65         vis[x] = 1;
66     }
67 }
68 
69 int main()
70 {
71     int n, m;
72     sion a, b;
73     while(cin >> n >> m)
74     {
75         init();
76         int s, t;
77         for(int i = 0; i < m; i++)
78         {
79             scanf("%d%d%d", &t, &a.nxp, &a.dis);
80             edge[t].push_back(a);
81             int temp = a.nxp;
82             a.nxp = t;
83             edge[temp].push_back(a);
84         }
85         scanf("%d%d", &s, &t);
86         dijkstra(s, n);
87         if(dic[t] >= INF)
88             printf("-1\n");
89         else
90             printf("%d\n", dic[t]);
91     }
92 }

 

posted @ 2016-06-26 21:38  Lweleth  阅读(203)  评论(0编辑  收藏  举报