zoukankan      html  css  js  c++  java
  • (最短路)AtCoder Beginner Contest 061 D

    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 (1≤iM) 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

    • 2≤N≤1000
    • 1≤Mmin(N(N−1),2000)
    • 1≤ai,biN(1≤iM)
    • aibi(1≤iM)
    • aiaj or bibj(1≤i<jM)
    • −109≤ci≤109(1≤iM)
    • 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

    由于出现负权值边,需要使用Bellman-Ford算法判断是否有和为正的环,并且此环必须还在某条能到n点的路径上。

    其中,为了方便处理,将边的权值先都乘-1,以将最长路变成最短路问题。

    利用Bellman-Ford算法循环顶点数-1之后如果还会更新dis,就说明有负环的性质,再加上延展这样的环的范围,如果能延展到顶点n,就为inf的情况,不然就输出最初记录的答案。

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <queue>
     8 #include <set>
     9 #include <map>
    10 #include <list>
    11 #include <stack>
    12 #include <vector>
    13 #define mp make_pair
    14 typedef long long ll;
    15 typedef unsigned long long ull;
    16 const int MAX=2e3+5;
    17 const int NAX=1e3+5;
    18 const ll INF=1e18+5;
    19 const double M=4e18;
    20 using namespace std;
    21 const int MOD=1e9+7;
    22 typedef pair<int,int> pii;
    23 const double eps=0.000000001;
    24 int n,m;
    25 ll dis[NAX];
    26 int from[MAX],to[MAX];
    27 bool neg[MAX];
    28 ll cost[MAX];
    29 ll an;
    30 int main()
    31 {
    32     scanf("%d%d",&n,&m);
    33     for(int i=1;i<=m;++i)
    34     {
    35         scanf("%d%d%lld",&from[i],&to[i],&cost[i]);
    36         cost[i]=-cost[i];
    37     }
    38     fill(dis+1,dis+1+n,INF);
    39     dis[1]=0;
    40     for(int i=0;i<n-1;++i)
    41     {
    42         for(int j=1;j<=m;++j)
    43         {
    44             if(dis[from[j]]==INF)
    45                 continue;
    46             if(dis[to[j]]>dis[from[j]]+cost[j])
    47             {
    48                 dis[to[j]]=dis[from[j]]+cost[j];
    49             }
    50         }
    51     }
    52     an=dis[n];
    53     for(int i=0;i<n-1;++i)
    54     {
    55         for(int j=1;j<=m;++j)
    56         {
    57             if(dis[from[j]]==INF)
    58                 continue;
    59             if(dis[to[j]]>dis[from[j]]+cost[j])
    60             {
    61                 neg[to[j]]=true;
    62                 dis[to[j]]=dis[from[j]]+cost[j];
    63             }
    64             if(neg[from[j]])
    65                 neg[to[j]]=true;
    66         }
    67     }
    68     if(neg[n])
    69         printf("inf
    ");
    70     else
    71         printf("%lld
    ",-an);
    72 }
    View Code
  • 相关阅读:
    [原]【实例化需求】1.FitNesse工具应用简介
    [原][问题解决]常见问题的5种解决办法(由Jenkins问题解决谈起)
    [原][自动化测试]Robot Framework Selenium基本使用
    [原]好玩的Linux,关于时间cal命令
    [原][问题解决]Romote Control 图形化界面显示问题解决办法
    【SBE】由需求管理谈起
    [Robot]关于robot的几个学习网站
    coolite中在UserControl中使用Coolite.AjaxMethods方法
    javascript实现页面加载进度条(转)
    coolite 在前台更新Window中控件的值
  • 原文地址:https://www.cnblogs.com/quintessence/p/6850839.html
Copyright © 2011-2022 走看看