connected
P352 connected component (undirected graph), strongly connected component (directed graph)
pata1034 head of a gang
Core code:
void dfs( int u,int& head,int &numMember,int &totalvalue )//head, numMember and totalvalue change with each recursive dfs, but their final results are subject to the last recursive (without backtracking) { vis[u]=true; if( w[u] > w[head] ) head=u; numMember++; for(int i=0;i<index;i++) { if( G[u][i]>0 )//It can reach point i from point u { totalvalue+= G[u][i];//If you can reach point i from point u, add the edge weight of u~i edge. Don't ask that point i has not been visited G[u][i]=G[i][u]=0; if(vis[i]==false) dfs(i,head,numMember,totalvalue); } } } void dfstrave() { for(int i=0;i<index;i++) { if(vis[i]==false) { int head=i,numMember=0,totalvalue=0; dfs(i,head,numMember,totalvalue); if( numMember>2 && totalvalue>k ) { gang[ int2str[head] ] = numMember; } } } }
Learning point 1: void dfs (int u, int & head, int & numMember, int & totalvalue) head, numMember and totalvalue change with each recursive dfs, but their final results are subject to the last recursive (without backtracking)
Learning point 2: the title needs to add all the edge weights of the connected graph, and the edge weights of edge 4 cannot be omitted, so the code uses if (G [u] [i] > 0) totalvalue + = g [u] [i], rather than if (G [u] [i] > 0 & & vis [i] = = false) totalvalue + = g [u] [i]
MST properties
Prime algorithm
The U set is the vertex set that falls in the minimum spanning tree, the TE set is the edge set in the minimum spanning tree, and the V-U set is the vertex set that has not yet fallen in the minimum spanning tree
Dijkstra algorithm
Used to solve the single source shortest path problem
Basic idea: set set set s for graph G(V,E), store the accessed vertices (these vertices have been found the shortest path), and then select the vertex with the smallest shortest path with the starting point s (recorded as U) from set V-S each time, access and join set s. Then let u be the intermediate point and optimize the shortest distance between the starting point s and all vertices v that can be reached from U. This operation is performed n times (n is the number of vertices) until the set s contains all vertices.
Adjacency matrix version
Time responsibility O (V^2)
Note input:
fill(G[0],G[0]+maxn*maxn,inf);//Don't leak for(int i=0;i<m;i++) { int A,B,len; scanf("%d %d %d",&A,&B,&len); G[A][B]=min(len,G[A][B]); G[B][A]=G[A][B];//Undirected graph }
Note that the following wording should not add vis[s]=true in advance, because the first step is to include the s point into the s set
int n,G[maxn][maxn]; int d[maxn]; bool vis[maxn]=; void dijkstra(int s)//s is the starting point { fill(d,d+maxn,inf); d[s]=0; for(int i=0;i<n;i++)//Cycle n times { int u=-1,MIN=inf; for(int j=0;j<n;j++)//Find the u nearest to the starting point in the V-S set { if(vis[j]==false && d[j]<MIN) { u=j; MIN=d[j]; } } if(u==-1) return;//The remaining vertices are not connected to the starting point vis[u]=true;//Add u to S set for(int v=0;v<n;v++) { //Take u as the relay node to relax if(vis[v]==false && G[u][v]!=inf && d[u]+G[u][v]<d[v] ) { d[v]=d[u]+G[u][v]; } } } }
Improvement of collar matrix version
Sometimes the problem has requirements. For example, when there are multiple shortest paths, we require the minimum point weight or the minimum edge weight (the edge weight is not necessarily the distance). We can record all the shortest paths first, and then dfs find out the compliance.
Because d[u]+G[u][v]==d[v], there may be multiple precursors. Use vector < int > pre [maxn] to store them
vector<int> pre[maxn]; void dijkstra(int s) { fill(d,d+maxn,inf); d[s]=0; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { int u=-1,MIN=inf; if( vis[j]==false && d[j]<MIN ) { u=j; MIN=d[j]; } } if(u==-1) return; vis[u]=true; for(int v=0;v<n;v++) { if(vis[v]==false && G[u][v]!=inf ) { if(d[u]+G[u][v] < d[v]) { d[v]=d[u]+G[u][v]; pre[v].clear();//Modify the precursor node of v to u pre[v].push_back(u); } else if(d[u]+G[u][v] == d[v]) { pre[v].push_back(u);//There are multiple precursor nodes } } } } }
subject
pata1003 Emergency
Meaning: give N cities and M undirected edges. Each city has a certain rescue team, and the edge rights of all sides are known. Find the sum of the number of shortest paths from the starting point to the end point and the number of rescue teams on the shortest path (the largest of multiple shortest paths)
num[i] represents the number of shortest paths from the starting point s to the vertex i, the initial num[s]=1, and the remaining num[i] is 0.
w[i] represents the sum of point weights from the starting point s to the vertex i on the shortest path.
#include<bits/stdc++.h> #define inf 0x3f3f3f3f using namespace std; const int maxn=510; int n,m; int G[maxn][maxn]; int d[maxn]; bool vis[maxn]=; int c1,c2;//starting point, end point int val[maxn];//Record point weight int num[maxn];//Record the number of shortest paths between the starting point and i int w[maxn];//In the case of the shortest path, record the maximum weight between the starting point and i void dijkstra(int s) { fill(d,d+maxn,inf); memset(num,0,sizeof num); memset(w,0,sizeof w); d[s]=0; //Initialize num and w num[s]=1; w[s]=val[s]; for(int i=0;i<n;i++) { int u=-1,MIN=inf; for(int j=0;j<n;j++) { if(vis[j]==false && d[j]<MIN) { u=j; MIN=d[j]; } } if(u==-1) return; vis[u]=true; for(int v=0;v<n;v++) { //Take u as the relay node to relax if(vis[v]==false && G[u][v]!=inf ) { if( d[u]+G[u][v]<d[v] ) { d[v]=d[u]+G[u][v]; num[v]=num[u]; w[v]=w[u]+val[v]; } else if( d[u]+G[u][v]==d[v] ) { num[v]+=num[u]; if( w[u]+val[v] > w[v]) w[v]=w[u]+val[v]; } } } } } int main() { cin>>n>>m>>c1>>c2; for(int i=0;i<n;i++) cin>>val[i]; fill(G[0],G[0]+maxn*maxn,inf); for(int i=0;i<m;i++) { int A,B,len; scanf("%d %d %d",&A,&B,&len); G[A][B]=min(len,G[A][B]); G[B][A]=G[A][B];//Undirected graph } dijkstra(c1); cout<<num[c2]<<" "<<w[c2]<<endl; return 0; }