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 }