usaco_comehome
2010-03-13 23:52
148 查看
Bessie Come Home
Kolstad & Burch
It's dinner time, and the cows are out in their separate pastures. Farmer John rings the bell so they will start walking to the barn. Your job is to figure out which one cow gets to the barn first (the supplied test data will always have exactly one fastest cow).
Between milkings, each cow is located in her own pasture, though some pastures have no cows in them. Each pasture is connected by a path to one or more other pastures (potentially including itself). Sometimes, two (potentially self-same) pastures are connected by more than one path. One or more of the pastures has a path to the barn. Thus, all cows have a path to the barn and they always know the shortest path. Of course, cows can go either direction on a path and they all walk at the same speed.
The pastures are labeled `a'..`z' and `A'..`Y'. One cow is in each pasture labeled with a capital letter. No cow is in a pasture labeled with a lower case letter. The barn's label is `Z'; no cows are in the barn, though.
Because the amount of vertices (=pastures+barn) is small, running Floyd/Warshall algorithm will solve the problem easily in time. If you think programming Floyd/Warshall is easier than Dijkstra, just do it. But you can also solve the problem running Dijkstra once, which of course speeds up your program quite a bit. Just initialise the barn as starting point, and the algorithm will find the distances from the barn to all the pastures which is the same as the distances from all the pastures to the barn because the graph is undirected. Using dijkstra for the solution would make far more complex data solvable within time. Here below you can see my implementation of this solution in Pascal. It might look big, but this way of partitioning your program keeps it easy to debug.
Kolstad & Burch
It's dinner time, and the cows are out in their separate pastures. Farmer John rings the bell so they will start walking to the barn. Your job is to figure out which one cow gets to the barn first (the supplied test data will always have exactly one fastest cow).
Between milkings, each cow is located in her own pasture, though some pastures have no cows in them. Each pasture is connected by a path to one or more other pastures (potentially including itself). Sometimes, two (potentially self-same) pastures are connected by more than one path. One or more of the pastures has a path to the barn. Thus, all cows have a path to the barn and they always know the shortest path. Of course, cows can go either direction on a path and they all walk at the same speed.
The pastures are labeled `a'..`z' and `A'..`Y'. One cow is in each pasture labeled with a capital letter. No cow is in a pasture labeled with a lower case letter. The barn's label is `Z'; no cows are in the barn, though.
PROGRAM NAME: comehome
INPUT FORMAT
Line 1: | Integer P (1 <= P <= 10000) the number of paths that interconnect the pastures (and the barn) |
Line 2..P+1: | Space separated, two letters and an integer: the names of the interconnected pastures/barn and the distance between them (1 <= distance <= 1000) |
SAMPLE INPUT (file comehome.in)
5 A d 6 B d 3 C e 9 d Z 8 e Z 3
OUTPUT FORMAT
A single line containing two items: the capital letter name of the pasture of the cow that arrives first back at the barn, the length of the path followed by that cow.SAMPLE OUTPUT (file comehome.out)
B 11
/* ID: guangxue1 PROG: comehome LANG: C++ */ #include <fstream> using namespace std; int min(int a,int b) {return a>b?b:a;} int sign[26]; int index(char a) { if(a>='a'&&a<='z') return a-'a'; else { return a-'A'+26; } } int distance1[52][52]; int main() { ifstream fin("comehome.in"); ofstream fout("comehome.out"); for(int i=0; i<52; ++i) for(int j=0; j<52; ++j) distance1[i][j]=99999999; int path; fin>>path; char pas1,pas2; int dis; for(int i=0; i<path; ++i) { fin>>pas1>>pas2>>dis; int a=index(pas1); int b=index(pas2); if(distance1[a][b]>dis) { distance1[a][b]=dis; distance1[b][a]=dis; } } for(int i=0; i<52; ++i) for(int j=0; j<52; ++j) if(distance1[i][j]==0) distance1[i][j]=99999999; for(int k=0; k<52; ++k) for(int i=0; i<52; ++i) for(int j=i+1; j<52; ++j) {distance1[i][j]=min(distance1[i][j],distance1[i][k]+distance1[k][j]); distance1[j][i]=distance1[i][j];} int fast=99999999; int memory; for(int i=26; i<51; ++i) if(distance1[51][i]<fast) {fast=distance1[51][i]; memory=i;} fout<<char('A'+memory-26)<<' '<<fast<<endl; return 0; }
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <ctype.h> #define INF 60000 /* bigger than longest possible path */ int dist[52][52]; int char2num(char c) { assert(isalpha(c)); if(isupper(c)) return c-'A'; else return c-'a'+26; } void main(void) { FILE *fin, *fout; int i, j, k, npath, d; char a, b; int m; fin = fopen("comehome.in", "r"); fout = fopen("comehome.out", "w"); assert(fin != NULL && fout != NULL); for(i=0; i<52; i++) for(j=0; j<52; j++) dist[i][j] = INF; for(i=0; i<26; i++) dist[i][i] = 0; fscanf(fin, "%d/n", &npath); for(i=0; i<npath; i++) { fscanf(fin, "%c %c %d/n", &a, &b, &d); a = char2num(a); b = char2num(b); if(dist[a][b] > d) dist[a][b] = dist[b][a] = d; } /* floyd warshall all pair shortest path */ for(k=0; k<52; k++) for(i=0; i<52; i++) for(j=0; j<52; j++) if(dist[i][k]+dist[k][j] < dist[i][j]) dist[i][j] = dist[i][k]+dist[k][j]; /* find closest cow */ m = INF; a = '#'; for(i='A'; i<='Y'; i++) { d = dist[char2num(i)][char2num('Z')]; if(d < m) { m = d; a = i; } } fprintf(fout, "%c %d/n", a, m); exit(0); }
Analysis of and code for Bessie Come Home by Wouter Waalewijn of The Netherlands
When looking at the problem the first thing you can conclude is that for the solution you will need to know all the distances from the pastures to the barn. After calculating them you only have to check all these distances and pick out the nearest pasture with a cow in it, and that's all.Because the amount of vertices (=pastures+barn) is small, running Floyd/Warshall algorithm will solve the problem easily in time. If you think programming Floyd/Warshall is easier than Dijkstra, just do it. But you can also solve the problem running Dijkstra once, which of course speeds up your program quite a bit. Just initialise the barn as starting point, and the algorithm will find the distances from the barn to all the pastures which is the same as the distances from all the pastures to the barn because the graph is undirected. Using dijkstra for the solution would make far more complex data solvable within time. Here below you can see my implementation of this solution in Pascal. It might look big, but this way of partitioning your program keeps it easy to debug.
Var Dist:Array [1..58] of LongInt; {Array with distances to barn} Vis :Array [1..58] of Boolean; {Array keeping track which pastures visited} Conn:Array [1..58,1..58] of Word; {Matrix with length of edges, 0 = no edge} Procedure Load; Var TF :Text; X,D,E:Word; P1,P2:Char; Begin Assign(TF,'comehome.in'); Reset(TF); Readln(TF,E); {Read number of edges} For X:=1 to E do Begin Read(TF,P1); {Read both pastures and edge length} Read(TF,P2); Read(TF,P2); {Add edge in matrix if no edge between P1 and P2 yet or} Readln(TF,D); {this edge is shorter than the shortest till now} If (Conn[Ord(P1)-Ord('A')+1,Ord(P2)-Ord('A')+1]=0) or (Conn[Ord(P1)-Ord('A')+1,Ord(P2)-Ord('A')+1]>D) then Begin Conn[Ord(P1)-Ord('A')+1,Ord(P2)-Ord('A')+1]:=D; Conn[Ord(P2)-Ord('A')+1,Ord(P1)-Ord('A')+1]:=D; End; End; Close(TF); For X:=1 to 58 do Dist[X]:=2147483647; {Set all distances to infinity} Dist[Ord('Z')-Ord('A')+1]:=0; {Set distance from barn to barn to 0} End; Procedure Solve; Var X,P,D:LongInt; {P = pasture and D = distance} Begin Repeat P:=0; D:=2147483647; For X:=1 to 58 do {Find nearest pasture not visited yet} If Not Vis[X] and (Dist[X]<D) then Begin P:=X; D:=Dist[X]; End; If (P<>0) then Begin Vis[P]:=True; {If there is one mark it visited} For X:=1 to 58 do {And update all distances} If (Conn[P,X]<>0) and (Dist[X]>Dist[P]+Conn[P,X]) then Dist[X]:=Dist[P]+Conn[P,X]; End; Until (P=0); {Until no reachable and unvisited pastures left} End; Procedure Save; Var TF :Text; X,BD:LongInt; {BD = best distance} BP :Char; {BP = best pasture} Begin BD:=2147483647; For X:=1 to 25 do {Find neares pasture} If (Dist[X]<BD) then Begin BD:=Dist[X]; BP:=Chr(Ord('A')+X-1); End; Assign(TF,'comehome.out'); Rewrite(TF); Writeln(TF,BP,' ',BD); {Write outcome to disk} Close(TF); End; Begin Load; Solve; Save; End.
相关文章推荐
- USACO 2.4 Bessie Come Home (comehome)
- usaco 2.4 comehome
- usaco 2.4 comehome 2008.7.16
- USACO2.4.4 Bessie Come Home (comehome)
- usaco2.4 comehome 最短路 Floyd, Dijkstra, Dijkstra优先队列优化
- USACO2.4.4 Bessie Come Home (comehome)
- usaco 2.4.4 comehome
- USACO Section 2.4 Bessie Come Home (comehome)
- 【USACO】第一章总结
- [USACO 09 Jan] Baric Bovine 气象牛 DP
- usaco 4.3.4 Street Race
- USACO-Section3.2 Magic Squares【宽度优先搜索】
- USACO Section 5.1 Starry Night
- 1666: [Usaco2006 Oct]Another Cow Number Game 奶牛的数字游戏
- BZOJ 1607: [Usaco2008 Dec]Patting Heads 轻拍牛头
- bzoj 3394: [Usaco2009 Jan]Best Spot 最佳牧场(floyd)
- 3390: [Usaco2004 Dec]Bad Cowtractors牛的报复
- usaco6.5.5 Checker Challenge
- 2442: [Usaco2011 Open]修剪草坪
- USACO2018FEB Gold