http://acm.sdibt.edu.cn/JudgeOnline/problem.php?id=1247
随着一种称为“¥”的超时空宇宙飞船的发明,一种叫做“¥¥”的地球与遥远的银河之间的商品进出口活动应运而生。¥¥希望从PluralZ星团中的一些银河进口商品,这些银河中的行星盛产昂贵的商品和原材料。初步的报告显示: (1)每个银河都包含至少一个和最多26个行星,在一个银河的每个行星用A~Z中的一个字母给以唯一的标识。 (2)每个行星都专门生产和出口一种商品,在同一银河的不同行星出口不同的商品。 (3)一些行星之间有超时空货运航线连接。如果行星A和B相连,则它们可以自由贸易;如果行星C与B相连而不与A相连,则A和C之间仍可通过B进行贸易,不过B要扣留5%的货物作为通行费。一般来说,只要两个行星之间可以通过一组货运航线连接,他们就可以进行贸易,不过每个中转站都要扣留5%的货物作为通行费。 (4)在每个银河至少有一个行星开放一条通往地球的¥航线。对商业来说,¥航线和其他星际航线一样。 ¥¥已经对每个行星的主要出口商品定价(不超过10的正实数),数值越高,商品的价值越高。在本地市场,越值钱的商品获利也越高。问题是要确定如果要考虑通行费是,哪个行星的商品价值最高。
输入包含若干银河的描述。每个银河的描述开始的第1行是一个整数n,表示银河的行星数。接下来的n行每行包括一个行星的描述,即: (1)一行用以代表行星的字母; (2)一个空格; (3)以d.dd的形式给出该行星的出口商品的价值; (4)一个空格; (5)一个包含字母和(或)字符“*”的字符串;字母表示一条通往该行星的货运航线;“*”表示该行星向地球开放¥货运航线。
对每个银河的描述,输出一个字母P表示在考虑通行费的前提下,行星P具有最高价值的出口商品。如果用有最高价值的出口商品的行星多于一个,只需输出字母序最小的那个行星。
5 E 0.01 *A D 0.01 A* C 0.01 *A A 1.00 EDCB B 0.01 A*
A分析:最短路的变形,求乘法最大值;
程序:
#include"string.h" #include"stdio.h" #include"queue" #include"map" #include"vector" #include"math.h" #define M 100 #define inf 100000000 #define eps 1e-10 using namespace std; struct node { int v; node(int vv) { v=vv; } }; vector<node>edge[M]; struct Node { char name[3]; double k; char str[222]; double ans; }p[M]; double dis[M]; int use[M]; void spfa(int s) { memset(dis,0,sizeof(dis)); queue<int>q; memset(use,0,sizeof(use)); dis[s]=1; use[s]=1; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); use[u]=0; for(int i=0;i<(int)edge[u].size();i++) { int v=edge[u][i].v; if(dis[v]<dis[u]*0.95) { dis[v]=dis[u]*0.95; if(!use[v]) { q.push(v); use[v]=1; } } } } } int main() { int n,i,j,r; while(scanf("%d",&n)!=-1) { for(i=0;i<=n;i++) edge[i].clear(); map<int,int>mp; for(i=1;i<=n;i++) { scanf("%s%lf%s",p[i].name,&p[i].k,p[i].str); mp[p[i].name[0]-'A']=i; } for(i=1;i<=n;i++) { for(r=0;p[i].str[r]!='\0';r++) { if(p[i].str[r]=='*') { edge[i].push_back(node(0)); edge[0].push_back(node(i)); continue; } j=mp[p[i].str[r]-'A']; edge[i].push_back(node(j)); edge[j].push_back(node(i)); } } spfa(0); //for(i=1;i<=n;i++) //printf("%s %.3lf\n",p[i].name,dis[i]); double max=0; int tep; for(i=1;i<=n;i++) { p[i].ans=dis[i]/0.95*p[i].k; if(max<p[i].ans) { max=p[i].ans; tep=i; } else if(fabs(max-p[i].ans)<eps) { if(p[tep].name[0]>p[i].name[0]) { tep=i; } } } printf("%c\n",p[tep].name[0]); } return 0; }