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.
3 4 5 2 3 4 1 2 1 1 3 5 2 3 7 2 4 3 3 4 5
This diagram shows the connections geometrically:
P2 P1 @--1--@ C1 \ |\ \ | \ 5 7 3 \ | \ \| \ C3 C2 @--5--@ P3 P4
8 OUTPUT DETAILS: Putting the cube in pasture 4 means: cow 1 walks 3 units; cow 2 walks 5 units; cow 3 walks 0 units -- a total of 8.
思路:用SPFA算出所有牧场到糖所在在的牧场的最短距离。在枚举所有糖可以在的牧场,算出奶牛所在牧场的最小距离加和就是答案
代码
/* ID:nealgav1 LANG:C++ PROG:butter */ #include<fstream> #include<queue> #include<vector> #include<cstring> using namespace std; ifstream cin("butter.in"); ofstream cout("butter.out"); const int oo=1e9; const int mm=1455; class node{public:int v,w;}; vector<node>edge[mm]; bool vis[mm];///判重 int cow[mm],dist[mm]; void SPFA(int u)///求出所有牧场到u牧场的最短距离 { int v,w; queue<int>Q; vector<node>::iterator it; memset(vis,0,sizeof(vis)); dist[u]=0; Q.push(u);vis[u]=true; while(!Q.empty()) { u=Q.front(); for(it=edge[u].begin();it!=edge[u].end();it++) { v=it->v;w=it->w; if(dist[u]<dist[v]-w) {dist[v]=dist[u]+w; if(!vis[v])Q.push(v); vis[v]=true; } } vis[u]=false; Q.pop(); } } int main() { int Cow,Pas,Path; int u,v,w; node t; cin>>Cow>>Pas>>Path; for(int i=0;i<Cow;i++)cin>>cow[i]; for(int i=1;i<=Pas;i++)edge[i].clear(); for(int i=0;i<Path;i++) { cin>>u>>v>>w; t.v=v;t.w=w; edge[u].push_back(t); t.v=u;edge[v].push_back(t); } int ans=oo; for(int i=1;i<=Pas;i++) { int num=0; for(int j=1;j<=Pas;j++)dist[j]=oo; SPFA(i);///将所有奶牛所在牧场的距离加和,求最小就是答案 for(int j=0;j<Cow;j++)num+=dist[cow[j]]; if(num<ans)ans=num; } cout<<ans<<"\n"; cin.close();cout.close(); }
Sweet Butter
We approach this problem directly, by calculating the distance from each cow to each pasture. Once this is done, we will simply have to sum the distances for each cow to get the total cost of putting the sugar cube at a given pasture. The key to a fast distance calculation is that our graph is quite sparse. Thus, we use Dijkstra with a heap to calculate the distance from a given cow to all pastures. This requires on the order of N*C*log(P), or about 7,000,000, operations.
#include <stdio.h> #include <string.h> const int BIG = 1000000000; const int MAXV = 800; const int MAXC = 500; const int MAXE = 1450; int cows; int v,e; int cow_pos[MAXC]; int degree[MAXV]; int con[MAXV][MAXV]; int cost[MAXV][MAXV]; int dist[MAXC][MAXV]; int heapsize; int heap_id[MAXV]; int heap_val[MAXV]; int heap_lookup[MAXV]; bool validheap(void){ for(int i = 0; i < heapsize; ++i){ if(!(0 <= heap_id[i] && heap_id[i] < v)){ return(false); } if(heap_lookup[heap_id[i]] != i){ return(false); } } return(true); } void heap_swap(int i, int j){ int s; s = heap_val[i]; heap_val[i] = heap_val[j]; heap_val[j] = s; heap_lookup[heap_id[i]] = j; heap_lookup[heap_id[j]] = i; s = heap_id[i]; heap_id[i] = heap_id[j]; heap_id[j] = s; } void heap_up(int i){ if(i > 0 && heap_val[(i-1) / 2] > heap_val[i]){ heap_swap(i, (i-1)/2); heap_up((i-1)/2); } } void heap_down(int i){ int a = 2*i+1; int b = 2*i+2; if(b < heapsize){ if(heap_val[b] < heap_val[a] && heap_val[b] < heap_val[i]){ heap_swap(i, b); heap_down(b); return; } } if(a < heapsize && heap_val[a] < heap_val[i]){ heap_swap(i, a); heap_down(a); } } int main(){ FILE *filein = fopen("butter.in", "r"); fscanf(filein, "%d %d %d", &cows, &v, &e); for(int i = 0; i < cows; ++i){ fscanf(filein, "%d", &cow_pos[i]); --cow_pos[i]; } for(int i = 0; i < v; ++i){ degree[i] = 0; } for(int i = 0; i < e; ++i){ int a,b,c; fscanf(filein, "%d %d %d", &a, &b, &c); --a; --b; con[a][degree[a]] = b; cost[a][degree[a]] = c; ++degree[a]; con[b][degree[b]] = a; cost[b][degree[b]] = c; ++degree[b]; } fclose(filein); for(int i = 0; i < cows; ++i){ heapsize = v; for(int j = 0; j < v; ++j){ heap_id[j] = j; heap_val[j] = BIG; heap_lookup[j] = j; } heap_val[cow_pos[i]] = 0; heap_up(cow_pos[i]); bool fixed[MAXV]; memset(fixed, false, v); for(int j = 0; j < v; ++j){ int p = heap_id[0]; dist[i][p] = heap_val[0]; fixed[p] = true; heap_swap(0, heapsize-1); --heapsize; heap_down(0); for(int k = 0; k < degree[p]; ++k){ int q = con[p][k]; if(!fixed[q]){ if(heap_val[heap_lookup[q]] > dist[i][p] + cost[p][k]){ heap_val[heap_lookup[q]] = dist[i][p] + cost[p][k]; heap_up(heap_lookup[q]); } } } } } int best = BIG; for(int i = 0; i < v; ++i){ int total = 0; for(int j = 0; j < cows; ++j){ total += dist[j][i]; } best <?= total; } FILE *fileout = fopen("butter.out", "w"); fprintf(fileout, "%d\n", best); fclose(fileout); return(0); }