zoukankan      html  css  js  c++  java
  • [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
    没有梦想,何谈远方
  • 相关阅读:
    Command模式应用实践
    .Net中的设计模式——Strategy模式
    PetShop之ASP.NET缓存
    征求书名
    PetShop之业务逻辑层设计
    Buider模式应用实践
    公告:目前博客园书业出版小组的工作进度
    “AS3.0高级动画编程”学习:第二章转向行为(下)
    as3: this,stage,root的测试
    As3.0中的位图(Bitmap/BitmapData)编程
  • 原文地址:https://www.cnblogs.com/zyue/p/3644236.html
Copyright © 2011-2022 走看看