Codeforces Round #Pi (Div. 2) E. President and Roads tarjan+最短路

#include<time.h>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<string>
#include<math.h>
#include<cctype>
#define ll long long
#define REP(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define REPP(i,a,b,t) for(int (i)=(a);(i)<=(b);(i)+=(t))
#define rep(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)
#define repp(i,a,b,t) for(int (i)=(a);(i)>=(b);(i)-=(t))
#define PII pair<int,int>
#define fst first
#define snd second
#define MP make_pair
#define PB push_back
#define RI(x) scanf("%d",&(x))
#define RII(x,y) scanf("%d%d",&(x),&(y))
#define RIII(x,y,z) scanf("%d%d%d",&(x),&(y),&(z))
#define DRI(x) int (x);scanf("%d",&(x))
#define DRII(x,y) int (x),(y);scanf("%d%d",&(x),&(y))
#define DRIII(x,y,z) int (x),(y),(z);scanf("%d%d%d",&(x),&(y),&(z))
#define RS(x) scanf("%s",x)
#define RSS(x,y) scanf("%s%s",x,y)
#define DRS(x) char x[maxn];scanf("%s",x)
#define DRSS(x,y) char x[maxn],y[maxn];scanf("%s%s",x,y)
#define MS0(a) memset((a),0,sizeof((a)))
#define MS1(a) memset((a),-1,sizeof((a)))
#define MS(a,b) memset((a),(b),sizeof((a)))
#define ALL(v) v.begin(),v.end()
#define SZ(v) (int)(v).size()

using namespace std;

const int MAXN=200000;
const int MAXM=200000;
__int64 INF=(1LL<<60);

struct Edge{
    int u,v;
    __int64 w;
    int i;
}e[MAXM];

struct Node{
    int v;
    __int64 w;
    bool operator <(const Node &r)const
    {
        return w>r.w;
    }
};

vector<Node> g[2][MAXN];
vector<Edge> G[MAXN];

bool in[MAXM];
bool vis[MAXN];
int n,m,s,t,u,v,index;
int dfn[MAXN];
__int64 d[2][MAXN],ddd,w;

void dijkstra(int flag)
{
    int a=flag?t:s;
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=MAXN;i++)
        d[flag][i]=INF;

    priority_queue<Node> q;
    d[flag][a]=0;
    q.push({a,0});
    Node temp;
    while(!q.empty())
    {
        temp=q.top();
        q.pop();
        int u=temp.v;
        if(vis[u])continue;
        vis[u]=true;
        for(int i=0;i<g[flag][u].size();i++)
        {
            int v=g[flag][u][i].v;
            __int64 w=g[flag][u][i].w;
            if(!vis[v]&&d[flag][v]>d[flag][u]+w)
            {
                d[flag][v]=d[flag][u]+w;
                q.push({v,d[flag][v]});
            }
        }
    }
}
int Targan(int u,int la)
{
    int lowu=dfn[u]=++index;
    for(int i=0;i<G[u].size();i++)
    {
        Edge en=G[u][i];
        if(dfn[en.v]==-1)
        {
            int lowv=Targan(en.v,en.i);
            lowu=min(lowu,lowv);
            if(lowv>dfn[u])
            {
                in[en.i]=true;
            }
        }
        else if(dfn[en.v]<dfn[en.u]&&en.i!=la)
            lowu=min(lowu,dfn[en.v]);
    }
    return lowu;
}

int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d%I64d",&u,&v,&w);
        e[i]={u,v,w,i};
        g[0][u].push_back({v,w});
        g[1][v].push_back({u,w});
    }

    dijkstra(0);
    dijkstra(1);

    ddd=d[0][t];
    for(int i=0;i<m;i++)
    {
        Edge en=e[i];
        if(d[0][en.u]+en.w==d[0][en.v]&&d[1][en.v]+en.w==d[1][en.u])
        {
            G[en.u].push_back({en.u,en.v,en.w,i});
            G[en.v].push_back({en.v,en.u,en.w,i});
        }
    }
    for(int i=0;i<=n;i++)
        dfn[i]=-1;
    Targan(s,-1);
    for(int i=0;i<m;i++)
    {
        if(ddd==INF)
        {
            printf("NO\n");
            continue;
        }
        if(in[i])
            printf("YES\n");
        else
        {
            __int64 aa=d[0][e[i].u]+d[1][e[i].v]+e[i].w-ddd+1;
            if(aa<e[i].w)
                printf("CAN %I64d\n",aa);
            else

                printf("NO\n");
        }
    }
    return 0;
}

时间: 2024-08-05 17:33:06

Codeforces Round #Pi (Div. 2) E. President and Roads tarjan+最短路的相关文章

Codeforces Round #Pi (Div. 2) E. President and Roads (最短路+强连通求割边)

题目地址:codeforces #pi (DIV2) E 题目很水..就是先求两边最短路,然后把可能为最短路的边挑出来,然后判断是否yes只需要转化成无向图跑一遍tarjan,找出割边,割边就是yes,然后剩下的边就让它的值为最短路-1就行了,如果-1后变成了非正数,就是no. 但是!!!居然卡spfa!!那是不是说cf以后就不能用可以卡的算法了..完全可以出组数据来卡这些算法...比如spfa,isap... 于是为了这题,又看了一遍迪杰斯特拉算法.. 代码如下: #include <cstd

map Codeforces Round #Pi (Div. 2) C. Geometric Progression

题目传送门 1 /* 2 题意:问选出3个数成等比数列有多少种选法 3 map:c1记录是第二个数或第三个数的选法,c2表示所有数字出现的次数.别人的代码很短,思维巧妙 4 */ 5 /************************************************ 6 * Author :Running_Time 7 * Created Time :2015-8-6 1:07:18 8 * File Name :C.cpp 9 *************************

构造 Codeforces Round #Pi (Div. 2) B. Berland National Library

题目传送门 1 /* 2 题意:给出一系列读者出行的记录,+表示一个读者进入,-表示一个读者离开,可能之前已经有读者在图书馆 3 构造:now记录当前图书馆人数,sz记录最小的容量,in数组标记进去的读者,分情况讨论一下 4 */ 5 /************************************************ 6 * Author :Running_Time 7 * Created Time :2015-8-6 0:23:37 8 * File Name :B.cpp 9

Codeforces Round #Pi (Div. 2) (STL专场)

Codeforces Round #Pi (Div. 2) A - Lineland Mail 水题,拼手速. /* * @author Novicer * language : C++/C */ #include<iostream> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<queue

Codeforces Round #Pi (Div. 2) (ABCD题解)

比赛链接:http://codeforces.com/contest/567 听说Round #Pi的意思是Round #314... A. Lineland Mail time limit per test:3 seconds memory limit per test:256 megabytes All cities of Lineland are located on the Ox coordinate axis. Thus, each city is associated with it

Codeforces Round #Pi (Div. 2)(A,B,C,D)

A题: 题目地址:Lineland Mail #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <sstream> #include <algorithm> #include <set> #include <queue> #include

Codeforces Round #Pi (Div. 2) B Berland National Library

思路:对于这道题,一开始并没有什么思路,但后来想了下,其实就是维护一个集合,每一个人都是不同的元素,满足了集合的互异性,而要求这个图书馆最小的容纳量,其实就是求这个集合的最大的元素量,假设在某个时刻集合里存在M个元素,是集合从开始到结束出现过的元素个数的最大值,那么就是这个图书馆的最小容纳量,如果最小容纳量比M小,那怎么容得下M个人?对于+,   他之前肯定是没进或者之前出来股,无论怎样,都要加进集合. 对于一个集合的操作,在cf种时间为上的比赛,自然选用stl的set,如果各位有更好的思路或实

Codeforces Round #Pi (Div. 2) —— C-Geometric Progression

题意: 现在有n个数,然后给出一个数k(代表的是等比数列中的那个公比),然后第二行给出n个数,代表的是这个序列. 最后的问题是叫你找出在这个序列中满足公比为k的三个数有几种,并输出方案总数. 思路: 这道题很巧妙啊,用到了map. 首先我们先记录下每种数出现过了几次,这里因为数太大了,直接用数组存会爆掉,所以改用map. 我们需要两个map,分别记为mp1,mp2. 然后在for的过程中,我们是以当前的那个数为第二项,然后去寻找它的mp1[a[i]*k](也就是第三项),寻找它的mp2[a[i]

Codeforces Round #Pi (Div. 2) —— D One-Dimensional Battle Ships

题目的意思是: 现在有一个长度为n,宽为1的方格,在上面可以放大小为1*a船,然后输入为n,k,a:分别为平地的大小,船的数量,船的长度. 一个叫alice的人已经在地图上摆好了船的位置. 然后bob总共可以有m次攻击的机会,然后他每次攻击的点为xi,但是alice并不会告诉它有没有打中(也就是说每次都认为他是miss的),问你,bob可以在第几次攻击的时候推测出alice在撒谎,如果推测不出来则输出-1. 这里每两条相邻的船不能相互接壤. 思路: 用set来维护每一段的区间. 首先,我们最多可