# DFS

## 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;
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;
}
}
}
void dfstrave()
{
for(int i=0;i<index;i++)
{
if(vis[i]==false)
{
if( numMember>2 && totalvalue>k )
{
}
}
}
}

```

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] # minimum spanning tree

## 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 # Shortest path algorithm

## 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.

Time responsibility O (V^2)
Note input:

```fill(G,G+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]={false};
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
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]={false};
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,G+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;
}
```

Posted on Sat, 20 Nov 2021 00:57:06 -0500 by TimTimTimma