现在是晚餐时间,而母牛们在外面分散的牧场中。 农民约翰按响了电铃,所以她们开始向谷仓走去。 你的工作是要指出哪只母牛会最先到达谷仓(在给出的测试数据中,总会有且只有一只最快的母牛)。 在挤奶的时候(晚餐前),每只母牛都在她自己的牧场上,一些牧场上可能没有母牛。 每个牧场由一条条道路和一个或多个牧场连接(可能包括自己)。 有时,两个牧场(可能是字母相同的)之间会有超过一条道路相连。 至少有一个牧场和谷仓之间有道路连接。 因此,所有的母牛最后都能到达谷仓,并且母牛总是走最短的路径。 当然,母牛能向着任意一方向前进,并且她们以相同的速度前进。 牧场被标记为'a'..'z'和'A'..'Y',在用大写字母表示的牧场中有一只母牛,小写字母中则没有。 谷仓的标记是'Z',注意没有母牛在谷仓中。
注意'm'和'M'不是同一个牧场否则错误上面的意思是说:输入数据中可能会同时存在M,m(郁闷ing),比如
M a a m m z
第 1 行: 整数 P(1<= P<=10000),表示连接牧场(谷仓)的道路的数目。
第 2 ..P+1行: 用空格分开的两个字母和一个整数:
被道路连接牧场的标记和道路的长度(1<=长度<=1000)。
单独的一行包含二个项目:最先到达谷仓的母牛所在的牧场的标记,和这只母牛走过的路径的长度。
5
A d 6
B d 3
C e 9
d Z 8
e Z 3
B 11
思路分析:读入时稍微处理一下就好,很简单,注意自己和自己不能联通。
但是,想着连连next数组,写了个SPFA,SB的全跑一遍,60,发现并不会写无向图的next!!!
还是先写正常的flyod吧。。。

1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 int dis[60],st[10010],ed[10010],dui[60],f[30],next[10010],point[10010],v[10010]; 7 int n,m; 8 bool b[60]; 9 void MapB() 10 { 11 int i; 12 char a,c; 13 m=0; 14 for (i=1;i<=n;i++) 15 { 16 cin>>a>>c>>v[i]; 17 if (a>='A' && a<='Z') 18 { 19 st[i]=int(a)-64; 20 if (!b[st[i]] && a!='Z') 21 { 22 f[++m]=st[i]; 23 b[st[i]]=false; 24 } 25 } 26 if (a>='a' && a<='z') 27 st[i]=int(a)-70; 28 if (c>='A' && c<='Z') 29 { 30 31 ed[i]=int(c)-64; 32 /* if (!b[ed[i]] && c!='Z') 33 { 34 f[++m]=ed[i]; 35 b[ed[i]]=false; 36 }*/ 37 } 38 if (c>='a' && c<='z') 39 ed[i]=int(c)-70; 40 next[i]=point[st[i]]; 41 point[st[i]]=i; 42 } 43 } 44 void mlSPFA() 45 { 46 int i,j; 47 int xl,now; 48 int h=0;int t=1; 49 int minn=9999999; 50 int x; 51 for (i=1;i<=m;i++) 52 { 53 memset(dui,0,sizeof(dui)); 54 memset(b,0,sizeof(b)); 55 memset(dis,0,sizeof(dis)); 56 h=0;t=1; 57 b[f[i]]=true; 58 dis[f[i]]=0; 59 dui[1]=f[i]; 60 while(h<t) 61 { 62 h++; 63 now=dui[h]; 64 xl=point[now]; 65 while(xl!=0) 66 { 67 dis[ed[xl]]=dis[now]+v[xl]; 68 if (!b[ed[xl]]) 69 { 70 dui[++t]=ed[xl]; 71 b[ed[xl]]=true; 72 } 73 xl=next[xl]; 74 } 75 b[now]=false; 76 } 77 if (dis[26]<minn) 78 { 79 minn=dis[26]; 80 x=f[i]; 81 } 82 } 83 cout<<char(x+64)<<' '<<minn; 84 } 85 int main() 86 { 87 //int i; 88 //int n,v; 89 //char a,b; 90 cin>>n; 91 MapB(); 92 mlSPFA(); 93 94 }
PS1:后来又把next数组改成无向图,但因为mod了27而不是52,sb一般调了好久,又加上了重边判断,各种xxx,好像还不到60.= =
PS2:第一遍flyod90,存在重复的边,所以取权最小的。因为不耐烦判重错了好几遍,A了。

1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 int b1[53][53],dis[60],st[10010],ed[10010],dui[60],f[30],v[10010],map[60][60]; 7 int n,m,vv,minn; 8 bool b[60]; 9 void MapB() 10 { 11 int i,j; 12 char a,c; 13 m=0; 14 for (i=1;i<=52;i++) 15 for (j=1;j<=52;j++) 16 map[i][j]=9999999; 17 for (i=1;i<=n;i++) 18 { 19 cin>>a>>c>>v[i]; 20 if (a>='A' && a<='Z') 21 { 22 st[i]=int(a)-64; 23 if (!b[st[i]] && a!='Z') 24 { 25 f[++m]=st[i]; 26 b[st[i]]=false; 27 } 28 } 29 if (a>='a' && a<='z') 30 st[i]=int(a)-70; 31 if (c>='A' && c<='Z') 32 { 33 34 ed[i]=int(c)-64; 35 if (!b[ed[i]] && c!='Z') 36 { 37 f[++m]=ed[i]; 38 b[ed[i]]=false; 39 } 40 } 41 if (c>='a' && c<='z') 42 ed[i]=int(c)-70; 43 if (!b1[st[i]][ed[i]]|| (v[i]<map[st[i]][ed[i]])) 44 { 45 map[st[i]][ed[i]]=map[ed[i]][st[i]]=v[i]; 46 b1[st[i]][ed[i]]=b1[ed[i]][st[i]]=true; 47 } 48 //next[i]=point[st[i]]; 49 //point[st[i]]=i; 50 //next[i+n]=point[ed[i]]; 51 //point[ed[i]]=i+n; 52 } 53 } 54 void mlflyod() 55 { 56 int i,j,k; 57 minn=99999999; 58 for (k=1;k<=52;k++) 59 for (i=1;i<=52;i++) 60 for (j=1;j<=52;j++) 61 if (i!=j && i!=k && j!=k) 62 map[i][j]=min(map[i][j],map[i][k]+map[k][j]); 63 for (i=1;i<=25;i++) 64 if (map[i][26]<minn) 65 { 66 minn=map[i][26]; 67 vv=i; 68 } 69 70 } 71 int main() 72 { 73 //int i; 74 //int n,v; 75 //char a,b; 76 char c; 77 cin>>n; 78 MapB(); 79 mlflyod(); 80 c=char(vv+64); 81 cout<<c<<' '<<minn; 82 }
本来是一道30min就应AC的题目,做了1天,原因:算法不熟练,考虑的太不周全,马力弱。