Solution to a problem --Acwing.342 roads and routes

Said front

  First, this question purely from the data departure, then, do directly SPFA, add a little optimization, SLF or LLL words are directly before.

  However, the spirit of rigorous scientific attitude , very lazy way is not recommended to use this opportunistic. And if the data structure is a special case, even if the increase will be optimized the same card. Therefore, positive solutions presented here.

Algorithms Introduction

Algorithm Description:

  Taking into account this problem has a very good nature: there is no necessity to edge ring.
  Is not considered to have edges, all edges to the configuration of FIG no add several communication blocks is set.
  Consider the directed edges, each of the communication block as points, each directed edge between these points is connected edges, a configuration of the entire FIG directed acyclic graph can be traversed directly topological sorting.
  For communication within each block can be done directly Dijkstra.

Algorithmic process:

  First read undirected edges, then the communication processing block, the recording block number in each communication point belongs and all points in each block contained in the communication.
  Read into the directed edges, each record of the communication block.
  To find the degree of communication block 0, and start topological sort.
  For each block traversal communication to do it again Heap_Dijkstra. Slack during operation, it is determined whether the two blocks in the same communication, if, it is placed in the Heap, or the communication block pointed to the relevant point of minus 1, then put into a queue topology It can be.

Time complexity analysis:

  Processing and communication block topological sort is linear, the bottleneck lies in the algorithm time Dijkstra.
  Disposed within the communication points to block x nx, number of sides mx.
  The total time for all Dijstra: m1logn1 + m2logn2 + ...... + mslogns <= m1logN + m2logN + ...... + mslogN = (m1 + m2 + ...... + ms) logN = MlogN.
  Therefore, the overall time complexity of the algorithm is O (N + MlogN) , a very high efficiency.

Reference Code:

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <queue>
  5 #include <vector>
  6 using namespace std;
  7 const int N=3e4+10,M=5e4+10,INF=0x3f3f3f3f;
  8 struct Edge{
  9     int to,ne,w;
 10 }edge[M<<2]; int idx;
 11 int h[N];
 12 int n,m1,m2,s;
 13 int dis[N],vis[N];
 14 int cnt_block;
 15 int id[N],ind[N];
 16 vector<int> block[N];
 17 queue<int> q;
 18 
 19 void add_edge(int u,int v,int w){edge[++idx]={v,h[u],w};h[u]=idx;}
 20 
 21 void dfs(int u,int id_block)
 22 {
 23     vis[u]=1;
 24     id[u]=id_block;
 25     block[id_block].push_back(u);
 26     
 27     for(int i=h[u];~i;i=edge[i].ne)
 28     {
 29         int to=edge[i].to;
 30         if(!vis[to])dfs(to,id_block);
 31     }
 32     
 33 }
 34 
 35 void dijkstra(int b)
 36 {
 37     priority_queue<pair<int,int> > heap;
 38     
 39     int sz=block[b].size();
 40     for(int i=0;i<sz;i++)
 41         heap.push(make_pair(-dis[block[b][i]],block[b][i]));
 42     
 43     while(!heap.empty())
 44     {
 45         int k=heap.top().second;
 46         heap.pop();
 47         
 48         if(vis[k])continue;
 49         vis[k]=1;
 50         
 51         for(int i=h[k];~i;i=edge[i].ne)
 52         {
 53             int to=edge[i].to,w=edge[i].w;
 54             if(dis[to]>dis[k]+w)
 55             {
 56                 dis[to]=dis[k]+w;
 57                 if(id[k]==id[to])heap.push(make_pair(-dis[to],to));
 58             }
 59             if(id[k]!=id[to]&&--ind[id[to]]==0)q.push(id[to]);
 60         }
 61     }
 62 }
 63 
 64 void topo_sort()
 65 {
 66     memset(dis,0x3f,sizeof dis);
 67     memset(vis,0,sizeof vis);
 68     dis[s]=0;
 69         
 70     for(int i=1;i<=cnt_block;i++)
 71         if(!ind[i])q.push(i);
 72         
 73     while(!q.empty())
 74     {
 75         int k=q.front();
 76         q.pop();
 77         
 78         dijkstra(k);
 79     }
 80 }
 81 
 82 int main()
 83 {
 84     memset(h,-1,sizeof h);
 85     scanf("%d%d%d%d",&n,&m1,&m2,&s);
 86     while(m1--)
 87     {
 88         int a,b,c;
 89         scanf("%d%d%d",&a,&b,&c);
 90         add_edge(a,b,c);
 91         add_edge(b,a,c);
 92     }
 93     
 94     for(int i=1;i<=n;i++)
 95         if(!vis[i])dfs(i,++cnt_block);
 96     
 97     while(m2--)
 98     {
 99         int a,b,c;
100         scanf("%d%d%d",&a,&b,&c);
101         add_edge(a,b,c);
102         ind[id[b]]++;
103     }
104     
105     topo_sort();
106     
107     for(int i=1;i<=n;i++)
108     {
109         if(dis[i]>INF/2)puts("NO PATH");
110         else printf("%d\n",dis[i]);
111     }
112     
113     return 0;
114 }

Guess you like

Origin www.cnblogs.com/ninedream/p/12208122.html