题意:有n个城市,每一个城市有一个拥挤度ai,从一个城市I到另一个城市J的时间为:(aJ-aI)^3,存在负环。问从第一个城市到达第k个城市所话的时间,如果不能到达,或者时间小于3输出?否则输出所花的时间。。
思路:用spfa找出的所有的负环,把所有负环能到的点都标记一下。。
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <queue> #include <stack> using namespace std; const int N = 209; const int INF = 0x3f3f3f3f; int n,re[N],m; struct LT{ int to,nex; } L[N*N]; int F[N],cnt; void add(int f,int t) { L[cnt].nex = F[f]; L[cnt].to = t; F[f] = cnt++; } int que[N*N]; int coun[N],cir[N],dis[N],inque[N]; int getdis(int i,int j) { int t = re[j] - re[i]; return t*t*t; } void dfs(int k) { cir[k] = 1; for(int i=F[k];i;i=L[i].nex) { if(!cir[L[i].to]) dfs(L[i].to); } } void solve() { memset(coun,0,sizeof(coun)); memset(cir,0,sizeof(cir)); memset(inque,0,sizeof(inque)); int front = 0, rear = 0; que[rear++] = 1; memset(dis,INF,sizeof(dis)); dis[1] = 0; while(rear>front) { int e = que[front++] ; inque[e] = false; coun[e]++; if(coun[e]>=n) { dfs(e); } for(int i=F[e];i;i=L[i].nex) { int to = L[i].to; if(cir[to]) continue; int k = getdis(e,to); if(dis[to]>dis[e]+k) { dis[to] = dis[e] + k; if(!inque[to]) { if(coun[to]>(n>>1)&&front>0) que[--front] = to; else que[rear++] = to; inque[to] = true; } } } } scanf("%d",&m); int a; while(m--) { scanf("%d",&a); if(cir[a]||dis[a]<3||dis[a]==INF) printf("?\n"); else printf("%d\n",dis[a]); } } int main() { freopen("in.txt","r",stdin); int cas,T=1; scanf("%d",&cas); while(cas--) { memset(F,0,sizeof(F));cnt = 1; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&re[i]); scanf("%d",&m); int a,b; for(int i=0;i<m;i++) { scanf("%d%d",&a,&b); add(a,b); } printf("Case %d:\n",T++); solve(); } return 0; }