[Luogu 2169] Regular Expression

Source: Internet
Author: User
[Luogu 2169] Regular Expression

<题目链接>

Thanks for question 0 x is.

I have never written a question in my memory for a long time...

Don't be fooled by the question name! This is not a regular expression question! It has nothing to do with character (string) processing! This is a graphic topic. Hello!

I'm not in a hurry. Capella, what are you in a hurry?

According to the question, the machines that can be locally transmitted are in the same strongly connected component, so Tarjan times and shrinks. In the process of contraction, select the short addition for the side between two SCC.

Here I use a map to record the ing from edge (pair <int, int>) to edge weight (INT), and then use map to determine whether to add edge.

The shortest path is short. Run a Dijkstra command (cherish your life and stay away from a dead Algorithm without explanation ).

Output the path from the SCC of 1 to the SCC of N.

#include <algorithm>#include <cstdio>#include <cstring>#include <map>#include <queue>#include <stack>#define nullptr NULLconst int MAXN = 200010; int n, m; namespace SCC{    bool exist[MAXN], vis[MAXN];     int num, sum, DFN[MAXN], low[MAXN], SCC[MAXN], dist[MAXN];     std :: stack<int> S;     struct Node    {        int index, dist;         Node(int index, int dist): index(index), dist(dist) {}        bool operator <(const Node& rhs) const        {            return dist > rhs.dist;         }    };     struct Graph    {        struct Edge        {            int to, w;             Edge *next;             Edge(int to, int w, Edge* next): to(to), w(w), next(next) {}            ~Edge(void)            {                if(next != nullptr)                    delete next;             }        }*head[MAXN];         Graph(int n)        {            std :: fill(head + 1, head + n + 1, (Edge*)nullptr);         }        ~Graph(void)        {            for(int i = 1; i <= n; ++i)                delete head[i];         }        void AddEdge(int u, int v, int w)        {            head[u] = new Edge(v, w, head[u]);         }    }*G, *Gnew;     void Tarjan(int u)    {        S.push(u);         exist[u] = true;         DFN[u] = low[u] = ++num;         int v;         for(Graph :: Edge *i = G -> head[u]; i != nullptr; i = i -> next)            if(!DFN[v = i -> to])            {                Tarjan(v);                 low[u] = std :: min(low[u], low[v]);             }            else if(exist[v])                low[u] = std :: min(low[u], DFN[v]);         if(DFN[u] == low[u])        {            ++sum;             do            {                exist[v = S.top()] = false;                 S.pop();                 SCC[v] = sum;             }            while(u ^ v);         }    }    void Shrink(void)    {        std :: map<std :: pair<int, int>, int> QAQ;         std :: pair<int, int> t;         Gnew = new Graph(sum);         for(int u = 1, v; u <= n; ++u)            for(Graph :: Edge *i = G -> head[u]; i != nullptr; i = i -> next)                if(!QAQ.count(t = std :: make_pair(SCC[u], SCC[v = i -> to])) || i -> w < QAQ[t])                {                    Gnew -> AddEdge(SCC[u], SCC[v], i -> w);                     QAQ[t] = i -> w;                 }    }    void Dijkstra(int S)    {        std :: priority_queue<Node> Q;         memset(dist, 0x3f, sizeof dist);         Q.push(Node(S, dist[S] = 0));         while(!Q.empty())        {            int u = Q.top().index, v;             Q.pop();             if(!vis[u])            {                vis[u] = true;                 for(Graph :: Edge *i = Gnew -> head[u]; i != nullptr; i = i -> next)                    if(dist[v = i -> to] > dist[u] + i -> w)                        Q.push(Node(v, dist[v] = dist[u] + i -> w));             }        }    }    void Solve(void)    {        for(int i = 1; i <= n; ++i)            if(!DFN[i])                Tarjan(i);         Shrink();         Dijkstra(SCC[1]);         printf("%d\n", dist[SCC[n]]);     }}int main(void){    scanf("%d %d", &n, &m);     SCC :: G = new SCC :: Graph(n);     for(int i = 1, u, v, w; i <= m; ++i)    {        scanf("%d %d %d", &u, &v, &w);         SCC :: G -> AddEdge(u, v, w);     }    SCC :: Solve();     return 0; }

Thank you for reading.

[Luogu 2169] Regular Expression

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.