Graph Theory (Not Completed)

Posted by zoobooboozoo on Mon, 05 Aug 2019 06:15:00 +0200

I. Definition of Graph

Graph consists of two sets, one is a non-empty but finite vertex set V, and the other is a set E describing the relational edges between sets.
Therefore, a graph can be expressed as G=(V,E). Each edge is a pair of vertices (v,w) and v,w < V.
Usually | V | and | E | denote the number of vertices and the number of edges. The vertex of a graph must not be empty, but the edge can be empty.

II. Terminology Relevant to Graph

Undirected graph
Adjacent Points: If <v.w> is any edge in an undirected graph. Then V and W are adjacent points. if < v, w > is any edge of a digraph, then V adjacent to W is called
Path, simple path, loop, no loop:
Path of a path in the graph refers to a sequence of vertices: v1,v2....vn. Any two adjacent vertices in the sequence can find the corresponding edges in the graph. The length of a path is the number of edges contained in the path.
A simple path means that all vertices are different except the first vertex of the path. A loop of a digraph, also known as a ring, refers to a path v1=vn. If there is no loop in a digraph, it is called acyclic graph. For undirected graphs, the minimum number of vertices constituting a loop is 3.
The degree of vertex v refers to the number of edges attached to the vertex. Vertices in a digraph are divided into degrees of entry and degrees of exit. In-degree of vertex v refers to the number of edges with vertex v as the end point. The out-degree of vertex v refers to the number of edges starting from vertex v.

Power and Network: Attach some data information to the edge. This information is usually called weight or cost. Graphs with weights on edges are called network graphs or networks.
Subgraph: For graphs G=(V,E) and G1=(V1,E1). If V1 is a subset of V and E1 is a subset of E, then G1 is a subgraph of G.
Spanning Tree and Spanning Forest: The spanning tree of a connected graph G is a minimal connected subgraph of G containing n vertices. It must contain n-1 edges, and spanning trees are not unique. When graph G is a tree if and only if G satisfies one of the following four conditions:
G has n-1 edges and no rings.
G has n-1 edges and G is connected.
Each vertex in G has and only one path connected.
G is connected, but deleting any edge will make it disconnected.
Generating forests: Because every connected component in a disconnected graph is a minimal connected subgraph. That is, a spanning tree can correspond to a connected component. All these connected components of the spanning tree constitute the forest.

3. Operation of Graphs

1. Storage

 1 #include<iosrteam>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<string>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<iomanip>
 8 using namespace std;
 9 namespace Moxing{
10     const int N=20005,M=100005;
11     int n,m,last[N],cnt;
12     struct node{
13         int to,dis,nxt;
14     }edge[M<<1];
15     void add(int from,int to,int dis){
16         edge[++cnt].to=to,edge[cnt].dis=dis,edge[cnt].nxt=last[from],last[from]=cnt;
17     } 
18     struct main{
19         main(){
20             n=read();int x,y,z;
21             for(int i=1;i<=m;i++){
22                 x=read(),y=read(),z=read();
23                 add(x,y,z),add(y,x,z);
24             }
25             exit(0);
26         }
27         int read(){
28             int x=0,f=1;
29             char ch=getchar();
30             while(!isdigit(ch)){
31                 if(ch=='-') f=-1;
32                 ch=getchar();
33             }
34             while(isdigit(ch)){
35                 x=x*10+ch-'0',ch=getchar();
36             }
37             return x*f;
38         }
39     }UniversalLove;
40 }
41 int main(){
42     Moxing::main();
43 }

 

2. Traversal

1 void dfs(int x){
2     vis[x]=1;
3     for(int i=last[x];i;i=edge[i].nxt){
4         int y=edge[i].to;
5         if(vis[y]) continue ;
6         dfs(y); 
7     }
8 }
 1 void bfs(){
 2     fill(deep+1,deep+1+n,0);deep[1]=1;
 3     queue<int>q;
 4     q.push(1);
 5     while(!q.empty()){
 6         int x=q.front(),q.pop();
 7         for(int i=last[x];i;i=edge[i].nxt){
 8             int y=edge[i].to;
 9             if(deep[y]) continue ;
10             deep[y]=deep[x]+1;
11             q.push(y);
12         }
13     }
14 }

III. Trees

 

1. Tree Chain Splitting

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<string>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<iomanip>
 8 using namespace std;
 9 namespace Moxing{
10     const int N=20005,M=100005;
11     int n,m,last[N],cnt;
12     struct node{
13         int to,dis,nxt;
14     }edge[M<<1];
15     void add(int from,int to,int dis){
16         edge[++cnt].to=to,edge[cnt].dis=dis,edge[cnt].nxt=last[from],last[from]=cnt;
17     } 
18     struct main{
19         main(){
20             n=read();int x,y,z;
21             for(int i=1;i<=m;i++){
22                 x=read(),y=read(),z=read();
23                 add(x,y,z),add(y,x,z);
24             }
25             exit(0);
26         }
27         int read(){
28             int x=0,f=1;
29             char ch=getchar();
30             while(!isdigit(ch)){
31                 if(ch=='-') f=-1;
32                 ch=getchar();
33             }
34             while(isdigit(ch)){
35                 x=x*10+ch-'0',ch=getchar();
36             }
37             return x*f;
38         }
39     }UniversalLove;
40 }
41 int main(){
42     Moxing::main();
43 }

2. Diameter of trees

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<string>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<iomanip>
 8 using namespace std;
 9 namespace Moxing {
10     //Definition of tree diameter:The longest path on a tree
11     const int N=1e5+5;
12     int last[N],cnt;
13     struct node {
14         int to,nxt,dis;
15     } edge[N<<1];
16     void add(int from,int to,int dis) {
17         edge[++cnt].to=to;
18         edge[cnt].dis=dis;
19         edge[cnt].nxt=last[from];
20         last[from]=cnt;
21     }
22     int p,q,fa[N],d[N],ans;
23     bool vis[N];
24 //d[x]:from x Node departure direction X The farthest node distance that a root subtree can reach
25 //d[x]=max(d[x],d[y]+edge[i].dis);
26     void dp(int x) {
27         vis[x]=1;
28         for(int i=last[x]; i; i=edge[i].nxt) {
29             int y=edge[i].to;
30             if(vis[y]) continue ;
31             dp(y);
32             ans=max(ans,d[x]+d[y]+edge[i].dis);
33             d[x]=max(d[x],d[y]+edge[i].dis);
34         }
35     }
36 //Starting from any node, the node farthest away from the starting point is determined as p
37 //slave nodes p Start, go through it again, and find out p The farthest node is marked as q
38     void dfs(int x) {
39         for(int i=last[x]; i; i=edge[i].nxt) {
40             int y=edge[i].to;
41             if(fa[x]==y) continue; //If you don't go back, you can also recurse the father node and omit it. fa Array space
42             fa[y]=x;
43             d[y]=d[x]+edge[i].dis;  //The longest path of the current node
44             dfs(y);
45         }
46     }
47     struct main {
48         main() {
49             int n;
50             scanf("%d",&n);
51             for(int i=1; i<=n; i++) fa[i]=i;
52             for(int i=1; i<=n-1; i++) {
53                 int x,y,cost;
54                 scanf("%d%d%d",&x,&y,&cost);
55                 add(x,y,cost);
56                 add(y,x,cost);
57             }
58             dfs(1);
59             int ansmax=0,ansindix=0;
60             for(int i=1; i<=n; i++) {
61                 if(d[i]>ansmax) ansmax=d[i],ansindix=i;
62                 d[i]=0;
63                 fa[i]=i;
64             }
65             dfs(ansindix);
66             for(int i=1; i<=n; i++) {
67                 cout<<d[i]<<' ';
68             }
69             cout<<endl;
70             //d[x]:from x Node departure direction X The farthest node distance that a root subtree can reach
71             //d[x]=max(d[x],d[y]+edge[i].dis);
72             memset(d,0,sizeof(d));
73             dp(1);
74             for(int i=1; i<=n; i++) {
75                 cout<<d[i]<<' ';
76             }
77             cout<<endl<<ans;
78             exit(0);
79         }
80     } UniversalLove;
81 }
82 int main() {
83     Moxing::main();
84 }

3. Center of gravity of trees

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<string>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<iomanip>
 8 using namespace std;
 9 namespace Moxing {
10     //Definition: if point u All subtrees of rooted trees (excluding the whole tree) are no larger than half of the total number of nodes.,Call point u Focus.
11 //Nature:
12 //1.The center of gravity must exist.
13 //2.The minimum distance from a point in the tree to the center of gravity.
14 //3.The tree adds or deletes a leaf, and the center of gravity moves the distance of at most one edge.
15 //4.Connect two trees through one side to form a new tree. The center of gravity must be on the path connecting the center of gravity of two trees.
16     const int N=1e5+5;
17     int last[N<<1],cnt;
18     struct node {
19         int to,nxt,dis;
20     } edge[N<<1];
21     void add(int from,int to,int dis) {
22         edge[++cnt].to=to;
23         edge[cnt].dis=dis;
24         edge[cnt].nxt=last[from];
25         last[from]=cnt;
26     }
27     int size[N],mx[N],rt=1,n;
28     bool vis[N];
29     //mx[x]Representation deletion x The size of the largest subtree after a node 
30     void root(int x,int fa) {
31         size[x]=1;
32         mx[x]=0;
33         for(int i=last[x]; i; i=edge[i].nxt) {
34             int y=edge[i].to;
35             if(!vis[y]&&y!=fa) {
36                 root(y,x);
37                 size[x]+=size[y];
38                 mx[x]=max(mx[x],size[y]);
39             }
40         }
41         mx[x]=max(mx[x],n-size[x]);
42         if(mx[x]<mx[rt]) rt=x;
43     }
44     struct main {
45         main() {
46             scanf("%d",&n);
47             for(int i=1; i<=n-1; i++) {
48                 int x,y,cost;
49                 scanf("%d%d%d",&x,&y,&cost);
50                 add(x,y,cost);
51                 add(y,x,cost);
52             }
53             root(1,1);
54             cout<<rt;
55             exit(0);
56         }
57     } UniversalLove;
58 }
59 int main() {
60     Moxing::main();
61 }

4. Recent Public Ancestors

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<string>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<iomanip>
 8 using namespace std;
 9 namespace Moxing{
10     //fa[x][k]: x 2^k Ancestors fa[x][k]=fa[fa[x][k-1]][k-1]
11     const int N=5e5+5,M=20;
12     int last[N],cnt,n,m,s,t,deep[N];
13     struct node {
14         int to,nxt;
15     } edge[N<<1];
16     void add(int from,int to) {
17         edge[++cnt].to=to;
18         edge[cnt].nxt=last[from];
19         last[from]=cnt;
20     }
21     struct nod{
22         int fa;
23     }f[N][M];
24     void dfs(int x){
25         for(int i=last[x];i;i=edge[i].nxt){
26             int y=edge[i].to;
27             if(deep[y]) continue ;
28             deep[y]=deep[x]+1;
29             f[y][0].fa=x;
30             dfs(y);
31         }
32     }
33     void cal(){
34         for(int i=1;i<=t;i++){
35             for(int j=1;j<=n;j++){
36                 f[j][i].fa=f[f[j][i-1].fa][i-1].fa;
37             }
38         }
39     }
40     int lca(int x,int y){
41         if(deep[y]>deep[x]) swap(x,y);
42         for(int i=t;i>=0;i--){
43             if(deep[f[x][i].fa]>=deep[y]) x=f[x][i].fa;
44         }
45         if(x==y) return x;
46         for(int i=t;i>=0;i--){
47             if(f[x][i].fa!=f[y][i].fa){
48                 x=f[x][i].fa,y=f[y][i].fa;
49             }
50         }
51         return f[x][0].fa;
52     }
53     struct main{
54         main(){
55             scanf("%d%d%d",&n,&m,&s);t=log(n)/log(2)+1;
56             for(int i=1;i<=n-1;i++){
57                 int x,y;
58                 scanf("%d%d",&x,&y);
59                 add(x,y);
60                 add(y,x);
61             }
62             deep[s]=1;f[s][0].fa=s;
63             dfs(s);
64             cal();
65             while(m--){
66                 int x,y;
67                 scanf("%d%d",&x,&y);
68                 printf("%d\n",lca(x,y));
69             }
70             exit(0);
71         }
72     }UniversalLove;
73 }
74 int main(){
75     Moxing::main(); 
76 }

5. Minimum Spanning Tree

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<string>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<iomanip>
 8 using namespace std;
 9 namespace Moxing{
10     const int N=1e5+5;
11     struct node{
12         int from,to,dis; 
13     }E[N<<1];
14     int n,m,fa[N],ans;
15     bool cmp(node a,node b){
16         return a.dis<b.dis;
17     }
18     int get(int x){
19         if(x==fa[x]) return x;
20         return fa[x]=get(fa[x]);
21     }
22     void kruskal(){
23         for(int i=1;i<=n;i++){
24             fa[i]=i;
25         }
26         sort(E+1,E+1+m,cmp);
27         for(int i=1;i<=m;i++){
28             int x=get(E[i].from),y=get(E[i].to);
29             if(x==y) continue ;
30             fa[x]=y;
31             ans+=E[i].dis;
32         }
33     }
34     struct main{
35         main(){
36             scanf("%d%d",&n,&m);
37             for(int i=1;i<=m;i++){
38                 scanf("%d%d%d",&E[i].from,&E[i].to,&E[i].dis);
39             }
40             kruskal();
41             printf("%d\n",ans);
42             exit(0);
43         }
44     }UniversalLove;
45 }
46 int main(){
47     Moxing::main();
48 }
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<string>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<iomanip>
 8 using namespace std;
 9 namespace Moxing {
10     int n,m,a[5005][5005],d[5005],ans;
11     bool vis[5005];
12     void prim() {
13     //    memset(vis,0,sizeof(vis));
14         memset(d,0x3f,sizeof(d));d[1]=0;
15         for(register int k=2; k<=n; k++) {
16             int x=0;
17             for(register int i=1; i<=n; i++) {
18                 if(!vis[i]&&(x==0||d[i]<d[x])) {
19                     x=i;
20                 }
21             }
22             vis[x]=1;//cout<<x<<' ';
23             for(register int i=1; i<=n; i++) {
24                 if(!vis[i]) d[i]=min(d[i],a[x][i]);
25                 //cout<<d[i]<<' ';
26             }
27         }
28     }
29     struct main{
30         main(){
31             scanf("%d%d",&n,&m);
32             memset(a,0x3f,sizeof(a));
33             for(int i=1;i<=n;i++) a[i][i]=0; 
34             for(int i=1;i<=m;i++){
35                 int x,y,z;
36                 scanf("%d%d%d",&x,&y,&z);
37                 a[y][x]=a[x][y]=min(a[x][y],z);
38             }
39             prim();
40             for(int i=2;i<=n;i++) ans+=d[i];
41             printf("%d\n",ans);
42             exit(0);
43         }
44     }UniversalLove;
45 }
46 int main(){
47     Moxing::main();
48 }

6. Sub-small spanning tree

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<string>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<iomanip>
  8 using namespace std;
  9 namespace Moxing {
 10 #define inf 2333333333333333;
 11     const int M=2e5+5;
 12     const int N=1e5+5;
 13     int n,m,last[N],cnt,fa[N],deep[N],t;
 14     bool pd[N];
 15     struct node {
 16         int from,to,nxt;
 17         long long dis;
 18     } E[M],edge[M<<1];
 19     bool cmp(node a,node b) {
 20         return a.dis<b.dis;
 21     }
 22     int get(int x) {
 23         if(x==fa[x]) return x;
 24         return fa[x]=get(fa[x]);
 25     }
 26     void add(int from,int to,long long dis) {
 27         edge[++cnt].from=from;
 28         edge[cnt].to=to;
 29         edge[cnt].dis=dis;
 30         edge[cnt].nxt=last[from];
 31         last[from]=cnt;
 32     }
 33     struct nod {
 34         int fa;
 35         long long maxx,minn;
 36     } f[N][19];
 37     void dfs(int x,int fa) {
 38         f[x][0].fa=fa;
 39         for(int i=last[x]; i; i=edge[i].nxt) {
 40             int y=edge[i].to;
 41             if(y==fa) continue ;
 42             f[y][0].fa=x;
 43             f[y][0].maxx=edge[i].dis;
 44             f[y][0].minn=-inf;
 45             deep[y]=deep[x]+1;
 46             dfs(y,x);
 47         }
 48     }
 49     void cal() {
 50         for(int i=1; i<=t; i++) {
 51             for(int j=1; j<=n; j++) {
 52                 f[j][i].fa=f[f[j][i-1].fa][i-1].fa;
 53                 f[j][i].maxx=max(f[j][i-1].maxx,f[f[j][i-1].fa][i-1].maxx);
 54                 f[j][i].minn=max(f[j][i-1].minn,f[f[j][i-1].fa][i-1].minn);
 55                 if(f[j][i-1].maxx>f[f[j][i-1].fa][i-1].maxx) f[j][i].minn=max(f[j][i].minn,f[f[j][i-1].fa][i-1].maxx);
 56                 else if(f[j][i-1].maxx<f[f[j][i-1].fa][i-1].maxx) f[j][i].minn=max(f[j][i].minn,f[j][i-1].maxx);
 57             }
 58         }
 59     }
 60     int lca(int x,int y) {
 61         if(deep[x]<deep[y]) swap(x,y);
 62         for(int i=t; i>=0; i--) {
 63             if(deep[f[x][i].fa]>=deep[y]) x=f[x][i].fa;
 64         }
 65         if(x==y) return x;
 66         for(int i=t; i>=0; i--) {
 67             if(f[x][i].fa!=f[y][i].fa) {
 68                 x=f[x][i].fa;
 69                 y=f[y][i].fa;
 70             }
 71         }
 72         return f[x][0].fa;
 73     }
 74     long long query(int x,int y,long long dis) {
 75         long long ans=-inf;
 76         for(int i=t; i>=0; i--) {
 77             if(deep[f[x][i].fa]>=deep[y]) {
 78                 if(dis!=f[x][i].maxx) ans=max(ans,f[x][i].maxx);
 79                 else ans=max(ans,f[x][i].minn);
 80                 x=f[x][i].fa;
 81             }
 82         }
 83         return ans;
 84     }
 85     void kruskal() {
 86         for(int i=1; i<=n; i++) {
 87             fa[i]=i;
 88         }
 89         sort(E+1,E+1+m,cmp);
 90         long long ans=0;
 91         for(int i=1; i<=m; i++) {
 92             int x=get(E[i].from),y=get(E[i].to),dis=E[i].dis;
 93             if(x==y) continue ;
 94             fa[x]=y;
 95             ans+=dis;
 96             pd[i]=1;
 97             add(E[i].to,E[i].from,dis);
 98             add(E[i].from,E[i].to,dis);
 99         }
100     }
101     struct main {
102         main() {
103             scanf("%d%d",&n,&m);
104             t=log(n)/log(2)+1;
105             for(int i=1; i<=m; i++) {
106                 scanf("%d%d%lld",&E[i].from,&E[i].to,&E[i].dis);
107             }
108             f[1][0].minn=-inf;
109             deep[1]=1;
110             dfs(1,-1);
111             cal();
112             long long res=inf;
113             for(int i=1; i<=m; i++) {
114                 if(!pd[i]) {
115                     int x=E[i].from,y=E[i].to,anc=lca(x,y);
116                     long long dis=E[i].dis;
117                     long long maxx=query(x,anc,dis),maxy=query(y,anc,dis);
118                     res=min(res,ans-max(maxx,maxy)+dis);
119                 }
120             }
121             printf("%lld\n",res);
122             exit(0);
123         }
124     } UniversalLove;
125 }
126 int main() {
127     Moxing::main();
128 }


kruskal algorithm has been proved that for any u,v has a maximum value of the edge weight between u and v which is less than or equal to the edge weight of the un-selected edge between u and v.
Unstrict sub-spanning tree: traverse each unselected edge (u,v,d) and replace it with the largest edge between u and V
The large value of the deposit order removes the case that the unselected edge right is equal to the original edge right, and only retains less than.

Topics: Android network less