AtCoder Beginner Contest 061 D - Score Attack(最短路变形,Bellman-Ford最短路算法)

D – Score Attack

Time limit : 2sec / Memory limit : 256MB

Score : 400 points

Problem Statement

There is a directed graph with N vertices and M edges. The i-th edge (1iM) points from vertex ai to vertex bi, and has a weight ci. We will play the following single-player game using this graph and a piece.

Initially, the piece is placed at vertex 1, and the score of the player is set to 0. The player can move the piece as follows:

  • When the piece is placed at vertex ai, move the piece along the i-th edge to vertex bi. After this move, the score of the player is increased by ci.

The player can end the game only when the piece is placed at vertex N. The given graph guarantees that it is possible to traverse from vertex 1 to vertex N.

When the player acts optimally to maximize the score at the end of the game, what will the score be? If it is possible to increase the score indefinitely, print inf.

Constraints

  • 2N1000
  • 1Mmin(N(N1),2000)
  • 1ai,biN(1iM)
  • aibi(1iM)
  • aiaj or bibj(1i<jM)
  • −109ci109(1iM)
  • ci is an integer.
  • In the given graph, there exists a path from vertex 1 to vertex N.

Input

Input is given from Standard Input in the following format:

N M  
a1 b1 c1  
a2 b2 c2
:  
aM bM cM  

Output

Print the maximum possible score at the end of the game, if it is finite. If it is possible to increase the score indefinitely, print inf.

Sample Input 1

Copy

3 3
1 2 4
2 3 3
1 3 5

Sample Output 1

Copy

7

There are two ways to move the piece to vertex N=3:

  • vertex 1 → vertex 2 → vertex 3 : score 4+3=7
  • vertex 1 → vertex 3 : score 5

Thus, the maximum possible score at the end of the game is 7.

Sample Input 2

Copy

2 2
1 2 1
2 1 1

Sample Output 2

Copy

inf

It is possible to increase the score indefinitely by alternating between vertex 1 and 2.

Sample Input 3

Copy

6 5
1 2 -1000000000
2 3 -1000000000
3 4 -1000000000
4 5 -1000000000
5 6 -1000000000

Sample Output 3

Copy

-5000000000
题目大意:有n个点以及m个有向边,同时在每个边上存在着一个权值,要求求出从1到n的最长路的权值多少
解题思路:考虑到这道题的存在负权情况,所以采用Bellman-Ford的算法,但是这道题求的是最长路,这就违背其算法计算最短路的初衷,一开始想的是利用树的直径,但是这道题好像跟树没有什么关系,就发现我们可以所有的权值取他的负数,这样意味着我求出来的最短路就是最长路了,同时要注意的是,这道题给的条件中,存在着回路的可能,意味着,有可能对于1到n的最长路不断地发生改变,所以为此,我们需要判一下是否存在回路,不过在这里要注意,一定判的是经过n-1轮松弛后,dis[n]的权值在经过第n轮后是否还发生改变,至于其他的路径是否发生改变,这个不是我们所关心的,我们关心的,只有dis[n]的变化
#include<iostream>    
#include<cstdio>  
#include<stdio.h>  
#include<cstring>    
#include<cstdio>    
#include<climits>    
#include<cmath>   
#include<vector>  
#include <bitset>  
#include<algorithm>    
#include <queue>  
#include<map>  
using namespace std; 
const long long int INF = 1LL << 50;
 
/*start:17/5/19 16:33*/
/*end:17/5/19   17:55  */
 
int w[2005],v[2005];
long long int lu[2005];
long long int l,dis[3005];
int n,m,x,y,i,k;
 
bool check;
 
int main()
{
	int j;
	memset(w,0,sizeof(w));
	memset(v,0,sizeof(v));
	memset(lu,0,sizeof(lu));
	cin>>n>>m;
	for(i=1;i<=m;i++)
	{
		cin>>x>>y>>l;
		w[i]=x;
		v[i]=y;
		lu[i]=-l;
	}
	for(i=1;i<=n;i++)
		dis[i]=INF;
	dis[1]=0;
	//MAX=INF;
	for(i=1;i<=n-1;i++)
	{	
		check=false;
		for(j=1;j<=m;j++)
		{
			if(dis[v[j]]>dis[w[j]]+lu[j])
			{
				check=true;
				dis[v[j]]=dis[w[j]]+lu[j];
			}
		}
		if(!check)
			break;
	}
	l=dis[n];
	for(j=1;j<=m;j++)
	{
		if(dis[v[j]]>dis[w[j]]+lu[j])
		{
			dis[v[j]]=dis[w[j]]+lu[j];
		}
	}
 
	if(dis[n]==INF)
	{
		cout<<"inf"<<endl;
		return 0;
	}
	if(dis[n]!=l)
	{
		cout<<"inf"<<endl;
		return 0;
	}
	cout<<-dis[n]<<endl;
	return 0;
}
    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/qq_34826781/article/details/72566212
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞