• E. President and Roads (CF Round #Pi (Div. 2)) 优先队列的Dij+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 froms to 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 or1 → 2 → 3 → 5 → 6.


    题意:n个点m条有向边,总统从起点s到终点t走最短路,问哪些边是一定会走的(输出YES),哪些边通过降低距离能够使它一定被经过(输出降低的距离)。否则输出NO。

    思路:正反两遍求最短路,然后依据dist把那些最短路上的边又一次建图,注意是无向图,然后用Tarjan求割边。最后每条边推断输出。竟然卡SPFA,改成Dij就过了,以后就用Dij吧,恩。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <string>
    #include <map>
    #include <stack>
    #include <vector>
    #include <set>
    #include <queue>
    #pragma comment (linker,"/STACK:102400000,102400000")
    #define pi acos(-1.0)
    #define eps 1e-6
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid+1,r
    #define FRE(i,a,b)  for(i = a; i <= b; i++)
    #define FREE(i,a,b) for(i = a; i >= b; i--)
    #define FRL(i,a,b)  for(i = a; i < b; i++)
    #define FRLL(i,a,b) for(i = a; i > b; i--)
    #define mem(t, v)   memset ((t) , v, sizeof(t))
    #define sf(n)       scanf("%d", &n)
    #define sff(a,b)    scanf("%d %d", &a, &b)
    #define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
    #define pf          printf
    #define DBG         pf("Hi
    ")
    typedef __int64 ll;
    using namespace std;
    
    #define INF 0x3f3f3f3f
    #define mod 1000000009
    const int maxn = 1005;
    const int MAXN = 100011;
    const int MAXM = 250010;
    const int N = 1005;
    
    int n,m,s,t;
    
    struct Edge
    {
        int u,v,next,id;
        ll len;
    }e1[MAXM],e2[MAXM];
    
    int head1[MAXN],head2[MAXN];
    
    typedef pair<ll,int>P;
    ll dist1[MAXN],dist2[MAXN];
    int num,tot,start,End;
    bool cut[MAXN];
    
    int Low[MAXN],DFN[MAXN],Stack[MAXN];
    bool Instack[MAXN];
    int Index,top;
    
    void init()
    {
        num=0;  tot=0;
        mem(head1,-1);
        memset(head2,-1,sizeof(head2));
    }
    
    void addedge(int u,int v,ll w,int id)
    {
        e1[num].u=u;
        e1[num].v=v;
        e1[num].len=w;
        e1[num].id=id;
        e1[num].next=head1[u];
        head1[u]=num++;
    }
    
    void addedge2(int u,int v,ll w,int id)
    {
        e2[tot].u=u;
        e2[tot].v=v;
        e2[tot].len=w;
        e2[tot].id=id;
        e2[tot].next=head2[u];
        head2[u]=tot++;
    }
    
    void Dijkstra(int s,int t,int head[],ll dist[],Edge edge[])
    {
        priority_queue<P,vector<P>,greater<P> >Q;
        dist[s]=0;
        Q.push(make_pair(0,s));
        while (!Q.empty())
        {
            P p=Q.top(); Q.pop();
            int u=p.second;
            if (dist[u]<p.first) continue;
            for (int i=head[u];~i;i=edge[i].next)
            {
                int v=edge[i].v;
                if (dist[v]>dist[u]+edge[i].len)
                {
                    dist[v]=dist[u]+edge[i].len;
                    Q.push(make_pair(dist[v],v));
                }
            }
        }
    }
    
    void Tarjan(int u,int pre)
    {
        int v;
        Low[u]=DFN[u]=++Index;
        Stack[top++]=u;
        Instack[u]=true;
        int pre_cnt=0;
        for (int i=head2[u];~i;i=e2[i].next)
        {
            v=e2[i].v;
            if (v==pre&&pre_cnt==0) { pre_cnt++;continue; }
            if (!DFN[v])
            {
                Tarjan(v,u);
                if (Low[u]>Low[v]) Low[u]=Low[v];
                if (Low[v]>DFN[u])
                    cut[e2[i].id]=true;
            }
            else if (Low[u]>DFN[v])
                Low[u]=DFN[v];
        }
        Instack[u]=false;
        top--;
    }
    
    void solve()
    {
        memset(DFN,0,sizeof(DFN));
        memset(Instack,false,sizeof(Instack));
        Index=top=0;
        for (int i=1;i<=n;i++)
            if (!DFN[i])
            Tarjan(i,i);
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("C:/Users/lyf/Desktop/IN.txt","r",stdin);
    #endif
        int i,j,u,v;
        ll w;
        while (~scanf("%d%d%d%d",&n,&m,&s,&t))
        {
            init();
            for (i=0;i<m;i++)
            {
                scanf("%d%d%I64d",&u,&v,&w);
                addedge(u,v,w,i);
                addedge2(v,u,w,i);
            }
            mem(dist1,INF);
            mem(dist2,INF);
            Dijkstra(s,t,head1,dist1,e1);
            Dijkstra(t,s,head2,dist2,e2);
            tot=0;
            memset(head2,-1,sizeof(head2));
            for (i=0;i<m;i++)
            {
                cut[i]=false;
                u=e1[i].u;
                v=e1[i].v;
                if (dist1[u]+dist2[v]+e1[i].len==dist1[t])
                {
                    addedge2(u,v,e1[i].len,i);
                    addedge2(v,u,e1[i].len,i);
                }
            }
            solve();
            for (i=0;i<m;i++)
            {
                u=e1[i].u;
                v=e1[i].v;
                if (cut[i]) printf("YES
    ");
                else if (dist1[u]+dist2[v]+e1[i].len==dist1[t])
                {
                    if (e1[i].len>1)
                        printf("CAN 1
    ");
                    else
                        printf("NO
    ");
                }
                else
                {
                    ll dd=dist1[t]-dist1[u]-dist2[v]-1;
                    if (dd<=0)
                        printf("NO
    ");
                    else
                        printf("CAN %I64d
    ",e1[i].len-dd);
                }
            }
        }
        return 0;
    }
    



  • 相关阅读:
    看opengl写代码(7) 使用混合数组(glInterLeavedArrays)
    三层交换机静态路由配置实现两网互通
    [leetcode] Insertion Sort List(python)
    Android 4.4环境搭建——配置AVD模拟器
    QlikView格式化某一个单元格
    浅谈触发器
    为什么镜像是左右而不是上下颠倒:4星|《环球科学》2018年08月号
    “第一公里”仍鲜被问津:4.5星|《财经》2018年第19期
    用故事做营销或管理,相关的8本书
    知识付费与内容创业相关的书9本
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/7091819.html
Copyright © 2020-2023  润新知