ZOJ1406,POJ1251

一个人想着一个人 提交于 2020-04-07 05:52:24

题意:求连接所有村子的最短路

prim+邻接矩阵

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 using namespace std;
 7 #define inf 999999
 8 #define N 30
 9 int n,dis[N],vis[N],g[N][N];
10 
11 int prim(int root)
12 {
13     for(int i=1; i<=n; i++)
14     dis[i]= g[i][root],vis[i]= 0;
15     dis[root]= 0;
16     vis[root]=1;
17     int cost= 0;
18     for(int T=1; T<=n-1; T++)
19     {
20         int mindis= inf,idx= -1;
21         for(int i=1; i<=n; i++)
22         {
23             if( vis[i]==0 )
24             {
25                 if( mindis>dis[i] )
26                 {
27                     mindis= dis[i];
28                     idx= i;
29                 }
30             }
31         }
32         cost+=mindis;
33         if( idx==-1 ) return -1;
34         vis[idx]= 1;
35         for(int i=1; i<=n; i++)
36         {
37             if( vis[i]==0 )
38             {
39                 if( dis[i]>g[i][idx] )
40                 dis[i]= g[i][idx];
41             }
42         }
43     }
44     return cost;
45 } 
46 
47 int main()
48 {
49     char op1[2],op2[2];
50     int co,w;
51     while(scanf("%d",&n)&&n)
52     {
53         for(int i=0; i<=N; i++)
54         for(int j=0; j<=N; j++)
55         {
56             if(i==j) g[i][j] = 0;
57             else g[i][j] = inf;
58         }
59         for(int i=1; i<=n-1; i++)
60         {
61             scanf("%s%d",op1,&co);
62             for(int j=1; j<=co; j++)
63             {
64                 scanf("%s%d",op2,&w);
65                 int u = op1[0]-'A'+1;
66                 int v = op2[0]-'A'+1;
67                 g[u][v] = g[v][u] = min(g[u][v],w);
68             }
69         }
70         int ans=prim(1);
71         printf("%d\n",ans);
72     }
73     return 0;
74 }
View Code

 

prim+优先队列

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<algorithm>
  6 #include<queue>
  7 using namespace std;
  8 #define M 200
  9 #define N 30
 10 const int inf= 999999;
 11 int n,size;
 12 typedef pair<int,int>mp;
 13 
 14 int head[N];
 15 int dis[N];
 16 int vis[N];
 17 
 18 struct Edge
 19 {
 20     int v,w,next;
 21     Edge(){}
 22     Edge(int V,int W,int NEXT):v(V),w(W),next(NEXT){}
 23 }edge[M];
 24 
 25 void Init()
 26 {
 27     memset(head,-1,sizeof(head));
 28     size = 0;
 29 }
 30 
 31 void InsertEdge(int u,int v,int w)
 32 {
 33     edge[size] = Edge(v,w,head[u]);
 34     head[u] = size++;
 35     edge[size] = Edge(u,w,head[v]);
 36     head[v] =size++;
 37 }
 38 
 39 int prim(int s)
 40 {
 41     int cost= 0;
 42     int times = 0;
 43     for(int i=1; i<=n; i++)
 44     {
 45         vis[i] = 0;
 46         dis[i] = inf;
 47     }
 48     mp p(0,s);

 49     priority_queue< mp,vector<mp>,greater<mp> > Q;
 50     Q.push(mp(0,s));
 51     while(!Q.empty()&&times<n)
 52     {
 53         do
 54         {
 55             p = Q.top();
 56             Q.pop();
 57         }while(vis[p.second]==1&&!Q.empty());
 58         if(vis[p.second]==0)
 59         {
 60             cost += p.first;
 61             vis[p.second] = 1;
 62             times ++;
 63             for(int i = head[p.second]; i!=-1; i=edge[i].next)
 64             {
 65                 int v = edge[i].v;
 66                 if(vis[v]==0)
 67                 {
 68                     if(edge[i].w < dis[v])
 69                     {
 70                         dis[v] = edge[i].w;
 71                         Q.push(mp(dis[v],v));
 72                     }
 73                 }
 74             }
 75         }
 76     }
 77     if(times<n) 
 78     return -1;
 79     return cost;
 80 } 
 81 int main()
 82 {
 83     char op1[2],op2[2];
 84     int co,w;
 85     while(scanf("%d",&n)&&n)
 86     {
 87         Init();
 88         for(int i=1; i<=n-1; i++)
 89         {
 90             scanf("%s%d",op1,&co);
 91             for(int j=1; j<=co; j++)
 92             {
 93                 scanf("%s%d",op2,&w);
 94                 int u = op1[0]-'A'+1;
 95                 int v = op2[0]-'A'+1;
 96                 int flag = 0;
 97                 for(int k=head[u]; k!=-1; k=edge[k].next)
 98                 {//重边的情况
 99                     if(v == edge[j].v)
100                     {
101                         if(w < edge[j].w)
102                         edge[j].w = w;
103                         flag = 1;
104                         break;
105                     }
106                 }
107                 if(flag) continue;
108                 InsertEdge(u,v,w);
109             }
110         }
111         int ans=prim(1);
112         printf("%d\n",ans);
113     }
114     return 0;
115 }
View Code

 

kruskal

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <algorithm>
  6 using namespace std;
  7 
  8 #define N 30
  9 #define M 100
 10 int n,m,father[N],rank[N],sum;
 11 struct Edge
 12 {
 13     int u;
 14     int v;
 15     int w;
 16 }edge[M];
 17 
 18 bool cmp(Edge a,Edge b)
 19 {
 20     return a.w < b.w ;
 21 }
 22 
 23 void Init()
 24 {
 25     for(int i=0; i<=n; i++)
 26     {
 27         father[i] = i;
 28         rank[i] = 1;
 29     }
 30 }
 31 
 32 int find(int x)
 33 {
 34     if(father[x] != x)
 35     {
 36         father[x] = find(father[x]);
 37     }
 38     return father[x];
 39 }
 40 
 41 void merge(int x,int y)
 42 {
 43     int xf = find(x);
 44     int yf = find(y);
 45     if(rank[x] > rank[y])
 46     {
 47         rank[xf] += rank[yf];
 48         father[yf] = xf;
 49     }
 50     else
 51     {
 52         rank[yf] += rank[xf];
 53         father[xf] = yf;
 54     }
 55 }
 56 
 57 void Kruskal()
 58 {
 59     int num = 0;
 60     for(int i=0; i<m; i++)
 61     {
 62         int u = edge[i].u;
 63         int v = edge[i].v;
 64         if(find(u) != find(v))
 65         {
 66             num++;
 67             sum += edge[i].w;
 68             merge(u,v);
 69         }
 70         if(num==n-1) break;
 71     }
 72 }
 73 
 74 int main()
 75 {
 76     char op1[2],op2[2];
 77     int co,w,cnt;
 78     while(scanf("%d",&n)&&n)
 79     {
 80         Init();
 81         cnt = 0;
 82         for(int i=1; i<n; i++)
 83         {
 84             scanf("%s%d",op1,&co);
 85             for(int j=1; j<=co; j++)
 86             {
 87                 scanf("%s%d",op2,&w);
 88                 int u = op1[0]-'A'+1;
 89                 int v = op2[0]-'A'+1;
 90                 edge[cnt].u = u ; edge[cnt].v = v ; edge[cnt].w = w;
 91                 cnt++;
 92             }
 93         }
 94         m = cnt;
 95         sort(edge,edge+m,cmp);
 96         sum = 0;
 97         Kruskal();
 98         printf("%d\n",sum);
 99     }
100     return 0;
101 } 
View Code

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!