题意:有n个城市,每个城市有拥挤值,有一些单向道路,从某个城市到另一个城市的花费是拥挤值差的三次方,当然可能是负的值。问从1点到某点最少的花费,若小于3或不能到达输出“?”
建图的边权是拥挤值差的三次方,跑一遍最短路然后按照询问输出就可以了。
1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 using namespace std; 5 6 int head[205],point[40005],val[40005],next[40005],size; 7 int dist[205],l[205],t,s[205],n; 8 bool vis[205],cir[205]; 9 10 void add(int a,int b,int v){ 11 point[size]=b; 12 val[size]=v; 13 next[size]=head[a]; 14 head[a]=size++; 15 } 16 17 void spfa(){ 18 int i; 19 memset(dist,-1,sizeof(dist)); 20 memset(vis,0,sizeof(vis)); 21 memset(s,0,sizeof(s)); 22 memset(cir,0,sizeof(cir)); 23 dist[1]=0; 24 queue<int>q; 25 q.push(1); 26 vis[1]=1; 27 while(!q.empty()){ 28 int u=q.front(); 29 q.pop(); 30 vis[u]=0; 31 if(s[u]>n){ 32 cir[u]=1; 33 continue; 34 } 35 for(i=head[u];~i;i=next[i]){ 36 int j=point[i]; 37 if((dist[j]==-1||dist[j]>dist[u]+val[i])&&!cir[j]){ 38 dist[j]=dist[u]+val[i]; 39 if(!vis[j]){ 40 q.push(j); 41 vis[j]=1; 42 s[j]++; 43 } 44 } 45 } 46 } 47 int m; 48 scanf("%d",&m); 49 for(i=1;i<=m;i++){ 50 scanf("%d",&t); 51 if(!cir[t]&&dist[t]>=3)printf("%d\n",dist[t]); 52 else printf("?\n"); 53 } 54 } 55 56 int main(){ 57 int T; 58 while(scanf("%d",&T)!=EOF){ 59 for(int q=1;q<=T;q++){ 60 scanf("%d",&n); 61 int i; 62 for(i=1;i<=n;i++){ 63 scanf("%d",&l[i]); 64 } 65 memset(head,-1,sizeof(head)); 66 size=0; 67 int m; 68 scanf("%d",&m); 69 for(i=1;i<=m;i++){ 70 int a,b; 71 scanf("%d%d",&a,&b); 72 int v=l[b]-l[a]; 73 v=v*v*v; 74 add(a,b,v); 75 } 76 printf("Case %d:\n",q); 77 spfa(); 78 } 79 } 80 return 0; 81 }
时间: 2024-10-09 12:48:46