这道题可以说是一个复活SPFA的题
因为数据比较小,SPFA也比较简单
那就复习(复读)一次SPFA吧
#include<iostream> #include<cstdio> #include<cmath> #include<queue> using namespace std; int bj=0; struct edge{ int next,to,dis; }; int d[1020]; int head[2500]; int dm,p,c,f,s; int rd[1120]; edge e[4000]; int vis[4000]; int size; int mmx=-1; void spfa(int x) //本题n(c),m(p+s)极小,因此SPFA在最坏复杂度下O(mn)也不会炸 { queue <int> q; q.push(x); vis[s]=1;//SPFA易忘操作,标记这个点是否在队中,如果不标记可能会出现死循环 while(!q.empty()) { int t=q.front(); q.pop(); if(rd[t]>=2*(c+p+f)) //当出现环的时候一般取一个点入队(n+m)次优化效率,为了防止毒瘤出题人*了2 { bj=1; break; } vis[t]=0; int i,j,k; for(i=head[t];i;i=e[i].next) { j=e[i].to; k=e[i].dis; if(d[t]-k+dm>d[j]) //至于不能取d[t]-k+d[j]>d[j]的原因是有可能d[j]包含了d[t] { d[j]=d[t]-k+dm; rd[j]++; if(vis[j]) continue; vis[j]=1; q.push(j); } } } } void addedge(int next,int to,int dis) { e[++size].next=head[next]; e[size].to=to; e[size].dis=dis; head[next]=size; } int main() { scanf("%d %d %d %d %d",&dm,&p,&c,&f,&s); int i,j; for(i=1;i<=p;i++) { int t1,t2; scanf("%d %d",&t1,&t2); addedge(t1,t2,0); //题上说了没有花费 } for(i=1;i<=c;i++) d[i]=dm; for(i=1;i<=f;i++) { int t1,t2,t3; scanf("%d %d %d",&t1,&t2,&t3); addedge(t1,t2,t3); } spfa(j); if(bj==1) //如果出现环 { printf("-1 "); return 0; } if(!bj) //如果没有 { for(i=1;i<=c;i++) mmx=max(d[i],mmx); } printf("%d",mmx); return 0; }