码迷,mamicode.com
首页 > 其他好文 > 详细

几个小模板:topology, dijkstra, spfa, floyd, kruskal, prim

时间:2015-03-15 02:02:38      阅读:245      评论:0      收藏:0      [点我收藏+]

标签:

1.topology:

技术分享
 1 #include <fstream>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <cmath>
 7 #include <cstdlib>
 8 
 9 using namespace std;
10 
11 #define EPS 1e-6
12 #define ll long long
13 #define INF 0x7fffffff
14 
15 const int N=1000;
16 const int N2=2000;
17 int fir[N],next_[N2],u[N2],v[N2];
18 int du[N];
19 int n,m;
20 
21 void Topology();
22 
23 int main(){
24     //freopen("D:\\input.in","r",stdin);
25     //freopen("D:\\output.out","w",stdout);
26     scanf("%d%d",&n,&m);
27     for(int i=1;i<=n;i++)   fir[i]=-1,du[i]=0;
28     for(int i=1;i<=m;i++){
29         scanf("%d%d",&u[i],&v[i]);
30         next_[i]=fir[u[i]];
31         fir[u[i]]=i;
32         du[v[i]]++;
33     }
34     Topology();
35     return 0;
36 }
37 void Topology(){
38     int top=-1;
39     for(int i=1;i<=n;i++)
40         if(du[i]==0)    du[i]=top,top=i;
41     for(int i=1;i<=n;i++){
42         if(top==-1){
43             cout<<"A cycle exists in the graph!"<<endl;
44             return;
45         }else{
46             int j=top;
47             top=du[top];
48             cout<<j<<endl;
49             for(int k=fir[j];k!=-1;k=next_[k]){
50                 if(--du[v[k]]==0)
51                     du[v[k]]=top,top=v[k];
52             }
53         }
54     }
55 }
View Code

2.dijkstra:

技术分享
 1 #include <fstream>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <cmath>
 7 #include <cstdlib>
 8 
 9 using namespace std;
10 
11 #define INF 0x7fffffff
12 
13 const int N=1000;
14 const int N2=1000000;
15 int node_num,edge_num,start_node,final_node;
16 int node_first[N],node_next[N2],node_begin[N2],node_end[N2],node_value[N2];
17 int dis[N],node_fa[N],road[N],road_len;
18 bool b[N];
19 
20 void TheBegin();//初始化
21 void Work();//存储无向图
22 void Dijkstra();//核心算法
23 void Road();//输出最短路径
24 
25 int main(){
26     //freopen("D:\\input.in","r",stdin);
27     //freopen("D:\\output.out","w",stdout);
28     scanf("%d%d%d%d",&node_num,&edge_num,&start_node,&final_node);
29     TheBegin();
30     Work();
31     Dijkstra();
32     Road();
33     return 0;
34 }
35 void TheBegin(){
36     for(int i=1;i<=node_num;i++){
37         node_first[i]=-1;
38         dis[i]=INF;
39     }
40 }
41 void Work(){
42     for(int i=1;i<=edge_num;i++){
43         scanf("%d%d%d",&node_begin[i],&node_end[i],&node_value[i]);
44         node_next[i]=node_first[node_begin[i]];
45         node_first[node_begin[i]]=i;
46         node_begin[i+edge_num]=node_end[i];
47         node_end[i+edge_num]=node_begin[i];
48         node_value[i+edge_num]=node_value[i];
49         node_next[i+edge_num]=node_first[node_begin[i+edge_num]];
50         node_first[node_begin[i+edge_num]]=i+edge_num;
51     }
52 }
53 void Dijkstra(){
54     dis[start_node]=0;
55     for(int k=1;k<=node_num;k++){
56         int x,m=INF;
57         for(int i=1;i<=node_num;i++)
58             if(!b[i]&&dis[i]<m) m=dis[x=i];
59         b[x]=1;
60         for(int i=node_first[x];i!=-1;i=node_next[i]){
61             if(!b[node_end[i]]&&dis[node_end[i]]>dis[x]+node_value[i]){
62                 dis[node_end[i]]=dis[x]+node_value[i];
63                 node_fa[node_end[i]]=x;
64             }
65         }
66     }
67     printf("%d\n",dis[final_node]);
68 }
69 void Road(){
70     for(int i=final_node;i!=start_node;i=node_fa[i])    road[road_len++]=i;
71     printf("the shortest road is:%d",start_node);
72     for(int i=road_len-1;i>=0;i--)  printf("-->%d",road[i]);
73     puts("");
74 }
View Code

3.dijkstra堆优化:

技术分享
 1 #include <fstream>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <queue>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <cstdlib>
 9 
10 using namespace std;
11 
12 #define INF 0x7fffffff
13 
14 const int N=1000;
15 const int N2=1000000;
16 int node_num,edge_num,start_node,final_node;
17 int node_first[N],node_next[N2],node_begin[N2],node_end[N2],node_value[N2];
18 int dis[N],node_fa[N],road[N],road_len;
19 bool b[N];
20 typedef pair<int,int> pii;
21 priority_queue<pii,vector<pii>,greater<pii> >pq;
22 
23 void TheBegin();//初始化
24 void Work();//存储无向图
25 void Dijkstra();//核心算法
26 void Road();//输出最短路径
27 
28 int main(){
29     //freopen("D:\\input.in","r",stdin);
30     //freopen("D:\\output.out","w",stdout);
31     scanf("%d%d%d%d",&node_num,&edge_num,&start_node,&final_node);
32     TheBegin();
33     Work();
34     Dijkstra();
35     Road();
36     return 0;
37 }
38 void TheBegin(){
39     for(int i=1;i<=node_num;i++){
40         node_first[i]=-1;
41         dis[i]=INF;
42     }
43 }
44 void Work(){
45     for(int i=1;i<=edge_num;i++){
46         scanf("%d%d%d",&node_begin[i],&node_end[i],&node_value[i]);
47         node_next[i]=node_first[node_begin[i]];
48         node_first[node_begin[i]]=i;
49         node_begin[i+edge_num]=node_end[i];
50         node_end[i+edge_num]=node_begin[i];
51         node_value[i+edge_num]=node_value[i];
52         node_next[i+edge_num]=node_first[node_begin[i+edge_num]];
53         node_first[node_begin[i+edge_num]]=i+edge_num;
54     }
55 }
56 void Dijkstra(){
57     dis[start_node]=0;
58     pq.push(make_pair(dis[start_node],start_node));
59     while(!pq.empty()){
60         pii tmp=pq.top();
61         pq.pop();
62         int x=tmp.second;
63         if(b[x])    continue;
64         b[x]=1;
65         for(int i=node_first[x];i!=-1;i=node_next[i]){
66             if(!b[node_end[i]]&&dis[node_end[i]]>dis[x]+node_value[i]){
67                 dis[node_end[i]]=dis[x]+node_value[i];
68                 pq.push(make_pair(dis[node_end[i]],node_end[i]));//队列里可能会加入重复元素
69                 node_fa[node_end[i]]=x;
70             }
71         }
72     }
73     printf("%d\n",dis[final_node]);
74 }
75 void Road(){
76     for(int i=final_node;i!=start_node;i=node_fa[i])    road[road_len++]=i;
77     printf("the shortest road is:%d",start_node);
78     for(int i=road_len-1;i>=0;i--)  printf("-->%d",road[i]);
79     puts("");
80 }
View Code

4.spfa:

技术分享
 1 #include <fstream>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <queue>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <cstdlib>
 9 
10 using namespace std;
11 
12 #define INF 0x7fffffff
13 
14 const int N=1000;
15 const int N2=1000000;
16 int node_num,edge_num,start_node,final_node;
17 int node_first[N],node_next[N2],node_begin[N2],node_end[N2],node_value[N2];
18 int dis[N],node_fa[N],road[N],road_len;
19 bool b[N];
20 queue<int> q;
21 
22 void TheBegin();//初始化
23 void Work();//存储无向图
24 void Spfa();//核心算法
25 void Road();//输出最短路径
26 
27 int main(){
28     //freopen("D:\\input.in","r",stdin);
29     //freopen("D:\\output.out","w",stdout);
30     scanf("%d%d%d%d",&node_num,&edge_num,&start_node,&final_node);
31     TheBegin();
32     Work();
33     Spfa();
34     Road();
35     return 0;
36 }
37 void TheBegin(){
38     for(int i=1;i<=node_num;i++){
39         node_first[i]=-1;
40         dis[i]=INF;
41     }
42 }
43 void Work(){
44     for(int i=1;i<=edge_num;i++){
45         scanf("%d%d%d",&node_begin[i],&node_end[i],&node_value[i]);
46         node_next[i]=node_first[node_begin[i]];
47         node_first[node_begin[i]]=i;
48         node_begin[i+edge_num]=node_end[i];
49         node_end[i+edge_num]=node_begin[i];
50         node_value[i+edge_num]=node_value[i];
51         node_next[i+edge_num]=node_first[node_begin[i+edge_num]];
52         node_first[node_begin[i+edge_num]]=i+edge_num;
53     }
54 }
55 void Spfa(){
56     dis[start_node]=0;
57     q.push(start_node);
58     while(!q.empty()){
59         int x=q.front();
60         q.pop();
61         b[x]=0;
62         for(int i=node_first[x];i!=-1;i=node_next[i]){
63             if(dis[node_end[i]]>dis[x]+node_value[i]){
64                 dis[node_end[i]]=dis[x]+node_value[i];
65                 node_fa[node_end[i]]=x;
66                 if(!b[node_end[i]]){
67                     q.push(node_end[i]);
68                     b[node_end[i]]=1;
69                 }
70             }
71         }
72     }
73     printf("%d\n",dis[final_node]);
74 }
75 void Road(){
76     for(int i=final_node;i!=start_node;i=node_fa[i])    road[road_len++]=i;
77     printf("the shortest road is:%d",start_node);
78     for(int i=road_len-1;i>=0;i--)  printf("-->%d",road[i]);
79     puts("");
80 }
View Code

5.floyd:

技术分享
 1 #include <fstream>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <cmath>
 7 #include <cstdlib>
 8 
 9 using namespace std;
10 
11 #define INF 0x7fffffff
12 
13 const int N=1000;
14 const int N2=1000000;
15 int node_num,edge_num,ans_num;
16 int dp[N][N];
17 
18 int main()
19 {
20     //freopen("D:\\input.in","r",stdin);
21     //freopen("D:\\output.out","w",stdout);
22     int u,v,w;
23     scanf("%d%d",&node_num,&edge_num);
24     for(int i=1;i<=node_num;i++)
25         for(int j=1;j<=node_num;j++)
26             dp[i][j]=(i==j?0:INF);
27     for(int i=1;i<=edge_num;i++)
28     {
29         scanf("%d%d%d",&u,&v,&w);
30         dp[u][v]=w;
31         dp[v][u]=w;
32     }
33     for(int k=1;k<=node_num;k++)
34         for(int i=1;i<=node_num;i++)
35             for(int j=1;j<=node_num;j++)
36                 if(dp[i][k]!=INF&&dp[k][j]!=INF)    dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]);
37     scanf("%d",&ans_num);
38     for(int i=1;i<=ans_num;i++)
39     {
40         scanf("%d%d",&u,&v);
41         printf("%d->%d: %d\n",u,v,dp[u][v]);
42     }
43     return 0;
44 }
View Code

6.kruskal(并查集):

技术分享
 1 #include <fstream>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <cmath>
 7 #include <cstdlib>
 8 
 9 using namespace std;
10 
11 #define EPS 1e-6
12 #define ll long long
13 #define INF 0x7fffffff
14 
15 const int N=1000;
16 const int N2=1000000;
17 int node_num,edge_num;
18 int node_u[N2],node_v[N2],node_w[N2],p[N],r[N2];
19 
20 inline int cmp(const int &a,const int &b)  { return node_w[a]<node_w[b]; }
21 inline int find(int x) { return p[x]==x?x:p[x]=find(p[x]); }
22 int Kruskal();
23 
24 int main(){
25     //freopen("D:\\input.in","r",stdin);
26     //freopen("D:\\output.out","w",stdout);
27     scanf("%d%d",&node_num,&edge_num);
28     for(int i=1;i<=edge_num;i++)
29         scanf("%d%d%d",&node_u[i],&node_v[i],&node_w[i]);
30     printf("%d\n",Kruskal());
31     return 0;
32 }
33 int Kruskal(){
34     int ans=0;
35     for(int i=1;i<=node_num;i++)   p[i]=i;
36     for(int i=1;i<=edge_num;i++)   r[i]=i;
37     sort(&r[1],&r[edge_num+1],cmp);
38     for(int i=1;i<=edge_num;i++){
39         int e=r[i];
40         int x=find(node_u[e]);
41         int y=find(node_v[e]);
42         if(x!=y)    ans+=node_w[e],p[x]=y;
43     }
44     return ans;
45 }
View Code

7.prim:

技术分享
 1 #include <fstream>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <cmath>
 7 #include <cstdlib>
 8 
 9 using namespace std;
10 
11 #define EPS 1e-6
12 #define ll long long
13 #define INF 0x7fffffff
14 
15 const int N=1000;
16 int a[N][N],distance_[N],node_num,edge_num;
17 bool choose[N];
18 
19 int Prim();
20 
21 int main(){
22     //freopen("D:\\input.in","r",stdin);
23     //freopen("D:\\output.out","w",stdout);
24     int u,v,w;
25     scanf("%d%d",&node_num,&edge_num);
26     for(int i=1;i<=node_num;i++)
27         for(int j=1;j<=node_num;j++)
28             a[i][j]=(i==j?0:INF);
29     for(int i=1;i<=edge_num;i++){
30         scanf("%d%d%d",&u,&v,&w);
31         a[u][v]=w;
32         a[v][u]=w;
33     }
34     printf("%d\n",Prim());
35     return 0;
36 }
37 int Prim(){
38     int ans=0;
39     for(int i=1;i<=node_num;i++)   choose[i]=0,distance_[i]=INF;
40     distance_[1]=0;
41     for(int i=1;i<=node_num;i++){
42         int x=-1;
43         for(int j=1;j<=node_num;j++)
44             if(!choose[j])
45                 if(x==-1)    x=j;
46                 else if(distance_[j]<distance_[x])    x=j;
47         choose[x]=1;
48         ans+=distance_[x];
49         for(int j=1;j<=node_num;j++)
50             if(!choose[j]&&a[x][j]!=INF){
51                 distance_[j]=min(distance_[j],a[x][j]);
52             }
53     }
54     return ans;
55 }
View Code

8.prim堆优化:

技术分享
 1 #include <fstream>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <cmath>
 7 #include <cstdlib>
 8 #include <queue>
 9 
10 using namespace std;
11 
12 #define EPS 1e-6
13 #define ll long long
14 #define INF 0x7fffffff
15 
16 const int N=1000;
17 const int N2=1000000;
18 int distance_[N],node_num,edge_num;
19 int node_first[N],node_next[N2],node_u[N2],node_v[N2],node_w[N2];
20 bool choose[N];
21 struct cmp{
22     bool operator()(const int &a,const int &b) const{
23         return distance_[a]>distance_[b];
24     }
25 };
26 priority_queue<int,vector<int>,cmp> pq;
27 
28 int prim();
29 
30 int main(){
31     //freopen("D:\\input.in","r",stdin);
32     //freopen("D:\\output.out","w",stdout);
33     scanf("%d%d",&node_num,&edge_num);
34     for(int i=1;i<=node_num;i++)
35         node_first[i]=-1;
36     for(int i=1;i<=edge_num;i++){
37         scanf("%d%d%d",&node_u[i],&node_v[i],&node_w[i]);
38         node_next[i]=node_first[node_u[i]];
39         node_first[node_u[i]]=i;
40         node_u[i+edge_num]=node_v[i];
41         node_v[i+edge_num]=node_u[i];
42         node_w[i+edge_num]=node_w[i];
43         node_next[i+edge_num]=node_first[node_u[i+edge_num]];
44         node_first[node_u[i+edge_num]]=i+edge_num;
45     }
46     printf("%d\n",prim());
47     return 0;
48 }
49 int prim(){
50     int ans=0;
51     for(int i=1;i<=node_num;i++)   choose[i]=0,distance_[i]=INF;
52     distance_[1]=0;
53     pq.push(1);
54     while(!pq.empty()){
55         int x=pq.top();
56         pq.pop();
57         if(choose[x])   continue;
58         choose[x]=1;
59         ans+=distance_[x];
60         for(int i=node_first[x];i!=-1;i=node_next[i])
61             if(!choose[node_v[i]]){
62                 if(distance_[node_v[i]]>node_w[i]){
63                     distance_[node_v[i]]=node_w[i];
64                     pq.push(node_v[i]);
65                 }
66             }
67     }
68     return ans;
69 }
View Code

 

几个小模板:topology, dijkstra, spfa, floyd, kruskal, prim

标签:

原文地址:http://www.cnblogs.com/jiu0821/p/4338666.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!