Description
奶牛们没钱了,正在找工作。农夫约翰知道后,希望奶牛们四处转转,碰碰运气。而且他还加了一条要求:一头牛在一个城市最多只能赚D(1 <= D <= 1,000)美元,然后它必须到另一座城市工作。当然,它可以在别处工作一阵后又回来原来的城市再最多赚D美元。而且这样往往返返的次数没有限制。 城市间有P (1 <= P <= 150)条单向路径连接,共有C(2 <= C <= 220)座城市,编号1..C. 贝希当前处在城市S (1 <= S <= C)。路径 i 从城市A_i 到城市B_i (1 <= A_i <= C; 1 <= B_i <= C),在路径上行走不用花任何费用。为了帮助贝希,约翰让它使用他的私人飞机服务。这项服务有F条(1 <= F <= 350)航线,每条航线是从城市J_i飞到另一座城市K_i (1 <=J_i <= C; 1 <= K_i <= C),费用是T_i (1 <= T_i <= 50,000)美元。如果贝希手中如果没有现钱,可以用以后赚的钱来付机票钱。贝希可以选择任何时候,在任何城市退休。如果在工作时间上不作限制,贝希总共可以赚多少钱呢? 如果赚的钱也不会出现限制,就输出-1。
Input
第1行: 5个空格分开的整数 D, P, C, F, S
第2..P+1行: 第 i+1行包含2个空格分开的整数,表示一条从A_i 到 B_i的单向路径
第P+2..P+F+1行: 第P+i 包含3个空格分开的整数,表示一条从J_i到K_i的单向航线,费用为T_i
Output
第1行: 在上述规则下的最多可赚的钱数。
Sample Input
100 3 5 2 1
1 5
2 3
1 4
5 2 150
2 5 120
1 5
2 3
1 4
5 2 150
2 5 120
Sample Output
250
HINT
样例说明:贝希可以从城市 1 到 5 再到 2 ,最后到 3, 总共赚 4*100 - 150 = 250 美元。
显然
为了拿个省一而开始刷水了。。
点有权值,边也有权值,所以应该考虑把点上的权值转到边上。
对于每条无费用边,把权值改成d,对每条有v费用边,权值改成d-v,显然最大路径权值和即是所求,有正环的时候就输出-1
有正环。。多别扭啊
所以把边权反过来,这样判负环即可
最后,因为会经过k个点k-1条边,所以点权要多算一次
这简直是无脑spfa。。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 using namespace std; 5 int head[100010]; 6 int tot[100010]; 7 int q[100010]; 8 int dis[100010]; 9 bool mrk[100010]; 10 struct edge{int to,next,v;}e[100000]; 11 int d,p,n,f,S,t=0,w=1,cnt; 12 inline void ins(int u,int v,int w) 13 { 14 e[++cnt].to=v; 15 e[cnt].next=head[u]; 16 e[cnt].v=w; 17 head[u]=cnt; 18 } 19 inline bool spfa() 20 { 21 memset(q,0,sizeof(q)); 22 memset(mrk,0,sizeof(mrk)); 23 memset(dis,127/3,sizeof(dis)); 24 dis[S]=-d;q[1]=S;mrk[S]=1; 25 t=0;w=1; 26 while (t<w) 27 { 28 int now=q[++t]; 29 for(int i=head[now];i;i=e[i].next) 30 if (dis[e[i].to]>dis[now]+e[i].v) 31 { 32 dis[e[i].to]=dis[now]+e[i].v; 33 if (!mrk[e[i].to]) 34 { 35 q[++w]=e[i].to; 36 mrk[e[i].to]=1; 37 tot[e[i].to]++; 38 if (tot[e[i].to]>n)return 1; 39 } 40 } 41 mrk[now]=0; 42 } 43 return 0; 44 } 45 int main() 46 { 47 scanf("%d%d%d%d%d",&d,&p,&n,&f,&S); 48 for (int i=1;i<=p;i++) 49 { 50 int x,y;scanf("%d%d",&x,&y); 51 ins(x,y,-d); 52 } 53 for(int i=1;i<=f;i++) 54 { 55 int x,y,z;scanf("%d%d%d",&x,&y,&z); 56 ins(x,y,z-d); 57 } 58 if (spfa()) 59 { 60 printf("-1"); 61 return 0; 62 } 63 int mx=d; 64 for (int i=1;i<=n;i++) 65 if (-dis[i]>mx)mx=-dis[i]; 66 printf("%d ",mx); 67 }