usaco Chapter 3 section 3.2 Sweet Butter

来源:互联网 发布:sql怎么导出数据库 编辑:程序博客网 时间:2024/05/17 04:48

/*

                                  Sweet Butter

Farmer John has discovered the secret to making the sweetest butter in all of Wisconsin: sugar. By placing a sugar cube out in the pastures, he knows the N (1 <= N <= 500) cows will lick it and thus will produce super-sweet butter which can be marketed at better prices. Of course, he spends the extra money on luxuries for the cows.

FJ is a sly farmer. Like Pavlov of old, he knows he can train the cows to go to a certain pasture when they hear a bell. He intends to put the sugar there and then ring the bell in the middle of the afternoon so that the evening's milking produces perfect milk.

FJ knows each cow spends her time in a given pasture (not necessarily alone). Given the pasture location of the cows and a description of the paths the connect the pastures, find the pasture in which to place the sugar cube so that the total distance walked by the cows when FJ rings the bell is minimized. FJ knows the fields are connected well enough that some solution is always possible.

此题对时间要求很严,我上来半个小时,写了个FLYOD第8个数据1.32s,经过修改时间更长。

然后看了网上的SPFA思想,自己实现了第8个数据要5s,更慢了,有研究了网上别人的写法,发现自己哎,代码的效率太低了。

*/

 

1、简单FLYOD

/*
ID: niepeng1
LANG: C++
TASK:butter
*/
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include<queue>

#define MMax 10000000
#define Maxcow 501
#define Maxpasture 801
#define Maxpath
//#define Max2 987654321
using namespace std;
FILE *in,*out;
int pasture[Maxpasture]={0};
int cost[Maxpasture]={0};
int map[Maxpasture][Maxpasture];
int main()
{
 in=fopen("butter.in","r");
 out=fopen("butter.out","w");
 int n,p,c,temx,temy,i,j,k;
 int min=MMax,sum=0;
 fscanf(in,"%d %d %d",&n,&p,&c);
 for(i=0;i<n;i++)
 {  
  fscanf(in,"%d",&temx);
  pasture[temx]++;
 }
 for(i=1;i<=p;i++)
  for(j=1;j<=p;j++)
   map[i][j]=MMax;
 for(i=0;i<c;i++)
 {
  fscanf(in,"%d %d",&temx,&temy);
  fscanf(in,"%d",&map[temx][temy]);
  map[temy][temx]=map[temx][temy];
 }

 for(k=1;k<=p;k++)
  for(i=1;i<=p;i++)
   for(j=1;j<=p;j++)
   {
    if( map[i][j]>map[i][k]+map[k][j])
     map[i][j]=map[i][k]+map[k][j];
   }
 for(i=1;i<=p;i++)
 {
  sum=0;
  for(j=1;j<=p;j++)
  {
   if( j!=i)
    sum+=pasture[j]*map[i][j];
  }
  if(min > sum)
   min=sum;
 }
// q.contains();
 fprintf(out,"%d/n",min);
 fclose(in);
 fclose(out);
    return 0;
}

2、自己实现的SPFA

 
/*
ID: niepeng1
LANG: C++
TASK:butter
*/
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include<queue>
#include<list>

#define MMax 10000000
#define Maxcow 501
#define Maxpasture 801
#define Maxpath
//#define Max2 987654321
using namespace std;
FILE *in,*out;
int pasture[Maxpasture]={0};
int cost[Maxpasture]={0};
int map[Maxpasture][Maxpasture];
int dest;

int main()
{
 in=fopen("butter.in","r");
 out=fopen("butter.out","w");
 int n,p,c,temx,temy,i,j,k;
 int min=MMax,sum=0;
 fscanf(in,"%d %d %d",&n,&p,&c);
 for(i=0;i<n;i++)
 {  
  fscanf(in,"%d",&temx);
  pasture[temx]++;
 }
 for(i=1;i<=p;i++)
  for(j=1;j<=p;j++)
   map[i][j]=MMax;
 for(i=0;i<c;i++)
 {
  fscanf(in,"%d %d",&temx,&temy);
  fscanf(in,"%d",&map[temx][temy]);
  map[temy][temx]=map[temx][temy];
 }
 list <int>q;
 int tem;
 for(i=1;i<=p;i++)
 {  
  //cout<<i<<endl;
  if(pasture[i]>0)
  {
   q.clear();
   //q.push_back(i);
   for(j=1;j<=p;j++)
   {
    if(map[i][j]<MMax && i!=j)
    {
     q.push_back(j);
    }

   }
   while(!q.empty())
   {
    tem=q.front();
    for(j=1;j<=p;j++)
    {
     if(i!=j && map[i][j]>map[i][tem]+map[tem][j])
     {
      map[i][j]=map[i][tem]+map[tem][j];
      dest=j;
      list<int>::iterator test;
      test=find(q.begin(), q.end(), j);
      if(test==q.end())
       q.push_back(j);
     }
    }
    q.pop_front();
   }
  }

 }
 for(i=1;i<=p;i++)
 {
  sum=0;
  for(j=1;j<=p;j++)//j为农场
  {
   if(pasture[j]>0 && j!=i)
    sum+=pasture[j]*map[j][i];
  }
  if(min > sum)
   min=sum;
 }

// q.contains();
 fprintf(out,"%d/n",min);
 fclose(in);
 fclose(out);
    return 0;
}
3、网上的代码,对比才发现差距

 

 /*
ID: niepeng1
LANG: C++
TASK:butter
*/
#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <memory.h>
using namespace std;

const int inf = 0x7ffffff;
int num[801];
int m[801][801], a[801][801];
int b[801];
int l[801];
int n, p, c, x;
int ans = inf;
int spfa(int k)
{
 memset(b,false,sizeof(b));
 memset(l,0x7F,sizeof(l));
 queue<int> q;
 q.push(k);
 b[k] = true;
 l[k] = 0;
 while (!q.empty())
 {
  int temp = q.front();
  for (int i = 1; i <= m[temp][0]; ++i)
  {
  //if (m[temp][i] != 0)
  //{
   if (a[temp][m[temp][i]] + l[temp] < l[m[temp][i]])//l记录从tem节点到i节点的距离
   {
    l[m[temp][i]] = a[temp][m[temp][i]] + l[temp];
    if (!b[m[temp][i]])//直接用bool数组标记是否使用该节点
    {
     q.push(m[temp][i]);
     b[m[temp][i]] = true;//这种方法更加快速,标记该节点是否使用
    }
   }
  //}
  }
  b[temp] = false;
  q.pop();
 
 }
 int res = 0;
  for (int i = 1; i <= p; ++i)
  {
  res += num[i] * l[i];
  }
  if (ans > res)
   ans = res;
  return res;
}

int main()
{
 ifstream fin("butter.in");
 ofstream fout("butter.out");
int i;
 fin >> n >> p >> c;
 for (i = 0; i < n; ++i)
 {
  fin >> x;
  ++num[x];
 }
 int s, e, len;
 for (i = 0; i < c; ++i)
 {
  fin >> s >> e >> len;
  ++m[s][0];//m[s][0]记录从农场连接的其他农场数目
  m[s][m[s][0]] = e;//记录第几个农场的编号
  a[s][e] = len;
  ++m[e][0];
  m[e][m[e][0]] = s;//同上反向再记录一次
  a[e][s] = len;//记录地图数组
 }
 int res = inf;
 for (i = 1; i <= p; ++i)
 {
  spfa(i);
 }
 fout << ans << endl;
 return 0;
}

 

 

原创粉丝点击