zoukankan      html  css  js  c++  java
  • codeforces 567 E President and Roads (优先队列+迪杰斯特拉+tarjan)

    E. President and Roads
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Berland has n cities, the capital is located in city s, and the historic home town of the President is in city t (s ≠ t). The cities are connected by one-way roads, the travel time for each of the road is a positive integer.

    Once a year the President visited his historic home town t, for which his motorcade passes along some path from s to t (he always returns on a personal plane). Since the president is a very busy man, he always chooses the path from s to t, along which he will travel the fastest.

    The ministry of Roads and Railways wants to learn for each of the road: whether the President will definitely pass through it during his travels, and if not, whether it is possible to repair it so that it would definitely be included in the shortest path from the capital to the historic home town of the President. Obviously, the road can not be repaired so that the travel time on it was less than one. The ministry of Berland, like any other, is interested in maintaining the budget, so it wants to know the minimum cost of repairing the road. Also, it is very fond of accuracy, so it repairs the roads so that the travel time on them is always a positive integer.

    Input

    The first lines contain four integers nms and t (2 ≤ n ≤ 105; 1 ≤ m ≤ 105; 1 ≤ s, t ≤ n) — the number of cities and roads in Berland, the numbers of the capital and of the Presidents' home town (s ≠ t).

    Next m lines contain the roads. Each road is given as a group of three integers ai, bi, li (1 ≤ ai, bi ≤ nai ≠ bi; 1 ≤ li ≤ 106) — the cities that are connected by the i-th road and the time needed to ride along it. The road is directed from city ai to city bi.

    The cities are numbered from 1 to n. Each pair of cities can have multiple roads between them. It is guaranteed that there is a path from sto t along the roads.

    Output

    Print m lines. The i-th line should contain information about the i-th road (the roads are numbered in the order of appearance in the input).

    If the president will definitely ride along it during his travels, the line must contain a single word "YES" (without the quotes).

    Otherwise, if the i-th road can be repaired so that the travel time on it remains positive and then president will definitely ride along it, print space-separated word "CAN" (without the quotes), and the minimum cost of repairing.

    If we can't make the road be such that president will definitely ride along it, print "NO" (without the quotes).

    Sample test(s)
    input
    6 7 1 6
    1 2 2
    1 3 10
    2 3 7
    2 4 8
    3 5 3
    4 5 2
    5 6 1
    output
    YES
    CAN 2
    CAN 1
    CAN 1
    CAN 1
    CAN 1
    YES
    input
    3 3 1 3
    1 2 10
    2 3 10
    1 3 100
    output
    YES
    YES
    CAN 81
    input
    2 2 1 2
    1 2 1
    1 2 2
    output
    YES
    NO
    Note

    The cost of repairing the road is the difference between the time needed to ride along it before and after the repairing.

    In the first sample president initially may choose one of the two following ways for a ride: 1 → 2 → 4 → 5 → 6 or 1 → 2 → 3 → 5 → 6.

    题意是说,给定一个有向图,对于每一条边,问是否是s到t的最短路上一定会经过的边.

    如果是就输出yes

    如果不是,问能否通过减少这条边的权值(减少的权值就是修理费用),使得这条边成为新的最短路上的边.

    对于一条边是否一定是最短路上的边,我们可以从s做一遍最短路,然后反响建边,从t再做一遍最短路.

    得到两个d1,d2数组

    如果一条边d1[u] + d2[v] + w(u, v) = 最短路,那这条边在最短路上的边.但是未必不能缺少.

    我们还要判断这条边是否是不能缺少的.

    不能缺少的意思是说,如果没有这条边,就不能构成最短路.

    那么这条边一定是桥.

    我们可以用tarjan算法求桥.

    据说是水题,不过图论还没怎么刷,所以对我来说还是很有难度的.

    只是基本懂了

    下面的代码是我仿照其他人的代码写出来的....求不鄙视 ><

    /*************************************************************************
        > File Name: code/cf/#314/E.cpp
        > Author: 111qqz
        > Email: rkz2013@126.com 
        > Created Time: 2015年08月17日 星期一 03时09分39秒
     ************************************************************************/
    
    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<map>
    #include<set>
    #include<queue>
    #include<vector>
    #include<stack>
    #define y0 abc111qqz
    #define y1 hust111qqz
    #define yn hez111qqz
    #define j1 cute111qqz
    #define tm crazy111qqz
    #define lr dying111qqz
    using namespace std;
    #define REP(i, n) for (int i=0;i<int(n);++i)  
    typedef long long LL;
    typedef pair<LL,LL> P;
    const int maxn = 200005;
    const LL mod1 = 1e9 + 7;
    const LL mod2 = 99999991;
    const LL inf = 1e15;
    
    struct Nod{
        LL b,val,next,idx;
        void init(LL b,LL val,LL next,LL idx){
            this->b=b;this->val=val;this->next=next;this->idx=idx;
        }
    }buf[2][maxn];
    LL len[2],E[2][maxn];
    LL n,m,s,t;
    LL dis[2][maxn],cnt[2][2][maxn],ans1[maxn],ans2[maxn];
    priority_queue<P,vector<P>,greater<P> > q;
    
    void init()
    {
        memset(E,-1,sizeof(E));
        memset(cnt,0,sizeof(cnt));
        len[0] = len[1] = 0;
    }
    
    void add_edge(LL a,LL b,LL val,LL idx)
    {
        buf[0][len[0]].init(b,val,E[0][a],idx);E[0][a]=len[0]++;
        buf[1][len[1]].init(a,val,E[1][b],idx);E[1][b]=len[1]++;
    }
    
    void dij(LL s,LL o)
    {
        while(!q.empty()) q.pop();
        fill(dis[o],dis[o]+maxn,inf);
        dis[o][s] = 0;cnt[o][0][s] = cnt[o][1][s] = 1;
        q.push(P(dis[o][s],s));
        LL u,v,i;
        while(!q.empty())
        {
            P p = q.top();q.pop();
            u = p.second;
            if(dis[o][u] != p.first) continue;
            for(i=E[o][u];i!=-1;i=buf[o][i].next)
        {
                v = buf[o][i].b;
                if(dis[o][v] > dis[o][u] + buf[o][i].val)
            {
                     dis[o][v] = dis[o][u] + buf[o][i].val;
                    cnt[o][0][v] = cnt[o][0][u];
                    cnt[o][1][v] = cnt[o][1][u];
                    q.push(P(dis[o][v],v));
                }else if(dis[o][v] == dis[o][u] + buf[o][i].val){
                     cnt[o][0][v] = (cnt[o][0][v] + cnt[o][0][u]) % mod1;
                    cnt[o][1][v] = (cnt[o][1][v] + cnt[o][1][u]) % mod2;
                }
            }
        }
    }
    
    int main()
    {
        init();
        LL u,v,i,a,b,val;
        LL cost;
        cin>>n>>m>>s>>t;
        for(i=1;i<=m;i++){
            cin>>a>>b>>val;
            add_edge(a,b,val,i);
        }
        dij(s,0);dij(t,1);
        for(u=1;u<=n;u++)
        {
            for(i=E[0][u];i!=-1;i=buf[0][i].next){
                v = buf[0][i].b;
                if(dis[0][u]+dis[1][v]+buf[0][i].val==dis[0][t]){
                     if(cnt[0][0][u]*cnt[1][0][v]%mod1 == cnt[0][0][t]&&
                       cnt[0][1][u]*cnt[1][1][v]%mod2 == cnt[0][1][t]){
                         ans1[buf[0][i].idx] = 1;
                        continue;
                    }
                }
                cost = dis[0][u]+dis[1][v]+buf[0][i].val-dis[0][t]+1;
                if(buf[0][i].val - cost > 0){
                    ans1[buf[0][i].idx] = 0;
                    ans2[buf[0][i].idx] = cost; 
                }else{
                    ans1[buf[0][i].idx] = -1;
                }
            }
        }
        for(i=1;i<=m;i++){
            if(ans1[i] == 1) printf("YES
    ");
            else if(ans1[i] == -1) printf("NO
    ");
            else{
            printf("CAN %I64d
    ",ans2[i]);
            }
        }
        return 0;
    }
  • 相关阅读:
    如何替换文件中的部分内容?
    将文件中的行倒序输出,并写入文件
    如何统计文件中除去空行的数据的行数?
    统计文件行数,统计特殊行(例如,统计含有数字的行数)
    Array,String,Set,Map
    python 操作 word 图片 消失
    es6
    Promise
    英文
    前端框架vue.js系列(9):Vue.extend、Vue.component与new Vue
  • 原文地址:https://www.cnblogs.com/111qqz/p/4735454.html
Copyright © 2011-2022 走看看