Cod sursa(job #2426133)

Utilizator MoldooooooooMoldoveanu Stefan Moldoooooooo Data 26 mai 2019 13:13:13
Problema Obiective Scor 35
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.08 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#define Inf 40001
using namespace std;
vector<vector<int> > Graph(32001);
int N, M, T, i, j;
///CTC
bool Check[32001], InS[32001];
stack<int> S;
pair<int, int> P[32001], List[64001]; int V, VP, Group[32001];
///CTC
///Dijkstra
vector<vector<pair<int, int> > > GraphCTC(32001);
int Dist[32001];
struct comp{
    bool operator()(int x, int y){
        if(Dist[x]>=Dist[y]) return 1;
        return 0;
    }
};
priority_queue<int, vector<int>, comp> Q; ///lucrez cu Dist[Q]
bool InQ[32001];
///Dijkstra
void Read();
void CTC();
void Tarjan(int i);
void Dijkstra(int a, int b);
int main()
{
    freopen("obiective.in", "r", stdin);
    freopen("obiective.out", "w", stdout);
    Read();
    CTC();
    scanf("%d", &T);
    for(i=1; i<=T; ++i){
        int a, b;
        scanf("%d%d", &a, &b);
        Dijkstra(Group[a], Group[b]);
    }
    return 0;
}
void Read(){
    scanf("%d%d", &N, &M);
    for(i=1; i<=N; ++i) Graph[i].push_back(0);
    for(i=1; i<=M; ++i){
        int x, y;
        scanf("%d%d", &x, &y);
        ++Graph[x][0];
        Graph[x].push_back(y);
        List[i]=make_pair(x, y);
    }
    return;
}
void CTC(){
    for(i=1; i<=N; ++i) if(Check[i]==false) Tarjan(i);
    for(i=1; i<=V; ++i) GraphCTC[i].push_back(make_pair(0, 0));
    for(i=1; i<=M; ++i) if(Group[List[i].first]!=Group[List[i].second]){
        ++GraphCTC[Group[List[i].first]][0].first;
        GraphCTC[Group[List[i].first]].push_back(make_pair(Group[List[i].second], 0));
        ++GraphCTC[Group[List[i].second]][0].first;
        GraphCTC[Group[List[i].second]].push_back(make_pair(Group[List[i].first], 1));
    }
    return;
}
void Tarjan(int i){
    int j;
    Check[i]=InS[i]=true;
    S.push(i);
    P[i].first=P[i].second=++VP;
    for(j=1; j<=Graph[i][0]; ++j){
        if(Check[Graph[i][j]]==false){
            Tarjan(Graph[i][j]);
            P[i].second=min(P[i].second, P[Graph[i][j]].second);
        }
        else if(InS[Graph[i][j]]==true) P[i].second=min(P[i].second, P[Graph[i][j]].first);
    }
    if(P[i].first==P[i].second){
        ++V;
        while(S.top()!=i){
            InS[S.top()]=false;
            Group[S.top()]=V;
            S.pop();
        }
        InS[S.top()]=false;
        Group[S.top()]=V;
        S.pop();
    }
    return;
}
void Dijkstra(int a, int b){
    int j;
    for(j=1; j<=V; ++j) {InQ[j]=false; Dist[j]=Inf;}
    Dist[a]=0; InQ[a]=true;
    Q.push(a);
    while(!Q.empty()){
        while(!Q.empty() && InQ[Q.top()]==false) Q.pop();
        if(Q.size()==0) break;
        int i=Q.top(); InQ[Q.top()]=false; Q.pop();
        for(j=1; j<=GraphCTC[i][0].first; ++j){
            if(Dist[i]+GraphCTC[i][j].second<Dist[GraphCTC[i][j].first]){
                Dist[GraphCTC[i][j].first]=Dist[i]+GraphCTC[i][j].second;
                Q.push(GraphCTC[i][j].first);
                if(InQ[GraphCTC[i][j].first]==false) InQ[GraphCTC[i][j].first]=true;
            }
        }
    }
    printf("%d\n", Dist[b]);
}