[USACO]Sweet Butter 多种解法

题意:给定一个无向稀疏图,有些节点里面有牛,问你求一点 所有牛到这点的路程和最小

解题思路:1)floyd 接受不了,极难优化,所以就有 n次 优先队列优化的dijkstra 算法,复杂度大概为V*V*lgV + V*E (其实这种方法接近算法导论上的johnson算法)

解题代码:

 1 /*
 2 ID: dream.y1
 3 PROG: butter
 4 LANG: C++
 5 */
 6 #include <iostream>
 7 #include <cstdio>
 8 #include <queue>
 9 #include <vector>
10 #include <climits>
11 using namespace std;
12 const int Ni = 1000;
13 const int INF = 1<<27;
14 struct node{
15     int x,d;
16     node(){}
17     node(int a,int b){x=a;d=b;}
18     bool operator < (const node & a) const
19     {
20         if(d==a.d) return x<a.x;
21         else return d > a.d;
22     }
23 };
24 vector<node> eg[Ni];
25 int dis[Ni],n;
26 void Dijkstra(int s)
27 {
28     int i;
29     for(i=0;i<=n;i++) dis[i]=INF;
30     dis[s]=0;
31     priority_queue<node> q;
32     q.push(node(s,dis[s]));
33     while(!q.empty())
34     {
35         node x=q.top();q.pop();
36         for(i=0;i<eg[x.x].size();i++)
37         {
38             node y=eg[x.x][i];
39             if(dis[y.x]>x.d+y.d)
40             {
41                 dis[y.x]=x.d+y.d;
42                 q.push(node(y.x,dis[y.x]));
43             }
44         }
45     }
46 }
47 int ans[1000];
48 int main()
49 {
50     freopen("butter.in","r",stdin);
51     freopen("butter.out","w",stdout);
52     int a,b,d,p,c;
53     scanf("%d %d %d",&p,&n,&c);
54     for(int i = 1;i <= p; i ++)
55         scanf("%d",&ans[i]);
56     for(int i=0;i<= n;i++) eg[i].clear();
57     while(c--)
58     {
59         scanf("%d%d%d",&a,&b,&d);
60         eg[a].push_back(node(b,d));
61         eg[b].push_back(node(a,d));
62     }
63     int min = INT_MAX;
64     for(int i = 1;i <= n ;i ++ )
65     {    
66       Dijkstra(i);
67       int tsum = 0  ;
68         for(int j = 1;j <= p;j ++)
69           tsum += dis[ans[j]];
70        if(tsum < min)
71            min = tsum ; 
72     }
73     printf("%d
",min);
74     return 0;
75 }
View Code

 2)SPFA  这种算法在本题上的表现比优先队列优化的dijkstra 更快,但是它的算法表现通常不稳定。

解题代码:

 1 // File Name: 2544_1.cpp
 2 // Author: darkdream
 3 // Created Time: 2014年04月04日 星期五 22时37分45秒
 4 /*
 5 ID: dream.y1
 6 PROG: butter
 7 LANG: C++
 8 */
 9 #include<vector>
10 #include<list>
11 #include<map>
12 #include<set>
13 #include<deque>
14 #include<stack>
15 #include<bitset>
16 #include<algorithm>
17 #include<functional>
18 #include<numeric>
19 #include<utility>
20 #include<sstream>
21 #include<iostream>
22 #include<iomanip>
23 #include<cstdio>
24 #include<cmath>
25 #include<cstdlib>
26 #include<cstring>
27 #include<ctime>
28 #include<climits>
29 #include<queue>
30 using namespace std;
31 
32 struct node{
33     int x, d ; 
34     node()
35     {}
36     node(int p,int q)
37     {
38         x = p; 
39         d = q; 
40     }
41 };
42 vector <node> edge[1000];
43 int n , m ; 
44 int dis[1000];
45 queue <int> lis;
46 int SPFA(int s)
47 {
48     for(int i = 1;i <= n;i ++) dis[i] = 1 << 27; 
49     dis[s] = 0 ; 
50     lis.push(s);
51     while(!lis.empty())
52     {
53         int k = lis.front();
54     //    printf("%d
",k);
55         lis.pop();
56         int n = edge[k].size();
57         for(int i = 0 ;i < n ;i ++)
58         {
59             if(dis[edge[k][i].x] > dis[k] + edge[k][i].d)
60             {
61                 dis[edge[k][i].x] = dis[k] + edge[k][i].d;
62                 lis.push(edge[k][i].x);
63             }
64         }
65     }
66     return 1;   
67 }
68 int main(){
69     freopen("butter.in","r",stdin);
70     freopen("butter.out","w",stdout);
71     int p ;     
72     scanf("%d %d %d",&p,&n,&m);
73 
74     int a[3000];
75     for(int i = 1;i <= p;i ++)
76        scanf("%d",&a[i]);      
77     for(int i =1 ;i <= n;i++)
78         edge[i].clear();
79     for(int i = 1;i <= m ;i ++)
80     { 
81         int a, b, c;
82         scanf("%d %d %d",&a,&b,&c);
83         edge[a].push_back(node(b,c));
84         edge[b].push_back(node(a,c));
85     }
86     int min = INT_MAX;
87     for(int i= 1;i <= n;i ++)
88     {   SPFA(i);
89         int tsum = 0 ; 
90         for(int j = 1;j <= p ;j ++)
91             tsum += dis[a[j]];
92         if(tsum < min )
93             min = tsum ; 
94     }
95     printf("%d
",min);
96     return 0;
97 }
View Code
没有梦想,何谈远方
原文地址:https://www.cnblogs.com/zyue/p/3644236.html