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
  • 相关阅读:
    DirectUI的初步分析转
    win32中调用Atl控件
    win32 DirectUI控件开发与调用指南
    sqlite in qt
    Visual Studio2010中使用IE调试Atl
    silveright使用配置文件转
    Windows phone app 商店认证注意事项简要认证规范指南
    Silverlight桌面部署器及其使用
    Lua语言如何调用自己编写的C DLL 转
    使用Visual Leak Detector for Visual C++ 捕捉内存泄露
  • 原文地址:https://www.cnblogs.com/quintessence/p/6850839.html
Copyright © 2011-2022 走看看