1.最小生成树:

kruscal:

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <stack>
  9. #define ll long long
  10. using namespace std;
  11. struct Edge
  12. {
  13. int nxt;
  14. int to;
  15. ll val;
  16. }edge[400005];
  17. struct E
  18. {
  19. int l,r;
  20. ll v;
  21. friend bool operator < (E a,E b)
  22. {
  23. return a.v<b.v;
  24. }
  25. }e[400005];
  26. int f[200005];
  27. int head[200005];
  28. int cnt=1;
  29. int n,m;
  30. void init()
  31. {
  32. for(int i=1;i<=n;i++)f[i]=i,head[i]=0;
  33. cnt=1;
  34. }
  35. void add(int l,int r,ll w)
  36. {
  37. edge[cnt].nxt=head[l];
  38. edge[cnt].to=r;
  39. edge[cnt].val=w;
  40. head[l]=cnt++;
  41. }
  42. int findf(int x)
  43. {
  44. return x==f[x]?x:f[x]=findf(f[x]);
  45. }
  46. void kruscal()
  47. {
  48. sort(e+1,e+m+1);
  49. int tot=0;ll ret=0;
  50. for(int i=1;i<=m;i++)
  51. {
  52. int f1=findf(e[i].l),f2=findf(e[i].r);
  53. if(f1==f2)continue;
  54. f[f1]=f2,tot++,ret+=e[i].v;
  55. if(tot==n-1)break;
  56. }
  57. if(tot==n-1)printf("%lld\n",ret);
  58. else printf("orz\n");
  59. }
  60. template <typename T>inline void read(T &x)
  61. {
  62. T f=1,c=0;char ch=getchar();
  63. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  64. while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
  65. x=c*f;
  66. }
  67. int main()
  68. {
  69. read(n),read(m);
  70. init();
  71. for(int i=1;i<=m;i++)read(e[i].l),read(e[i].r),read(e[i].v);
  72. kruscal();
  73. return 0;
  74. }

2.最短路:

spfa(最好不要写,他死了)...

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <stack>
  9. #define ll long long
  10. using namespace std;
  11. const int inf=0x3f3f3f3f;
  12. const ll INF=0x3f3f3f3f3f3f3f3fll;
  13. struct Edge
  14. {
  15. int nxt;
  16. int to;
  17. ll val;
  18. }edge[1000005];
  19. struct E
  20. {
  21. int l,r;
  22. ll v;
  23. friend bool operator < (E a,E b)
  24. {
  25. return a.v<b.v;
  26. }
  27. }e[500005];
  28. struct node
  29. {
  30. int p;ll v;
  31. node (){}
  32. node (int x,ll y):p(x),v(y){}
  33. friend bool operator < (node a,node b)
  34. {
  35. return a.v>b.v;
  36. }
  37. };
  38. int f[200005];
  39. int head[200005];
  40. ll dis[200005];
  41. bool used[200005];
  42. int cnt=1;
  43. int n,m,S,T;
  44. void init()
  45. {
  46. for(int i=1;i<=n;i++)f[i]=i,head[i]=0;
  47. cnt=1;
  48. }
  49. void add(int l,int r,ll w)
  50. {
  51. edge[cnt].nxt=head[l];
  52. edge[cnt].to=r;
  53. edge[cnt].val=w;
  54. head[l]=cnt++;
  55. }
  56. int findf(int x)
  57. {
  58. return x==f[x]?x:f[x]=findf(f[x]);
  59. }
  60. void kruscal()
  61. {
  62. sort(e+1,e+m+1);
  63. int tot=0;ll ret=0;
  64. for(int i=1;i<=m;i++)
  65. {
  66. int f1=findf(e[i].l),f2=findf(e[i].r);
  67. if(f1==f2)continue;
  68. f[f1]=f2,tot++,ret+=e[i].v;
  69. if(tot==n-1)break;
  70. }
  71. if(tot==n-1)printf("%lld\n",ret);
  72. else printf("orz\n");
  73. }
  74. void spfa(int st)
  75. {
  76. memset(dis,0x3f,sizeof(dis));
  77. dis[st]=0,used[st]=1;
  78. queue <int> M;
  79. M.push(st);
  80. while(!M.empty())
  81. {
  82. int u=M.front();
  83. M.pop();
  84. for(int i=head[u];i;i=edge[i].nxt)
  85. {
  86. int to=edge[i].to;
  87. if(dis[to]>dis[u]+edge[i].val)
  88. {
  89. dis[to]=dis[u]+edge[i].val;
  90. if(!used[to])used[to]=1,M.push(to);
  91. }
  92. }
  93. used[u]=0;
  94. }
  95. for(int i=1;i<=n;i++)
  96. {
  97. if(dis[i]==INF)printf("2147483647 ");
  98. else printf("%lld ",dis[i]);
  99. }
  100. }
  101. void diji(int st)
  102. {
  103. memset(dis,0x3f,sizeof(dis));
  104. dis[st]=0;
  105. priority_queue <node> M;
  106. M.push(node(st,0));
  107. while(!M.empty())
  108. {
  109. node temp=M.top();
  110. M.pop();
  111. int u=temp.p;
  112. if(used[u])continue;
  113. used[u]=1;
  114. for(int i=head[u];i;i=edge[i].nxt)
  115. {
  116. int to=edge[i].to;
  117. if(dis[to]>dis[u]+edge[i].val&&!used[to])dis[to]=dis[u]+edge[i].val,M.push(node(to,dis[to]));
  118. }
  119. }
  120. for(int i=1;i<=n;i++)printf("%lld ",dis[i]);
  121. }
  122. template <typename T>inline void read(T &x)
  123. {
  124. T f=1,c=0;char ch=getchar();
  125. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  126. while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
  127. x=c*f;
  128. }
  129. int main()
  130. {
  131. read(n),read(m),read(S);
  132. init();
  133. for(int i=1;i<=m;i++)
  134. {
  135. int x,y;ll z;
  136. read(x),read(y),read(z);
  137. add(x,y,z);//,add(y,x,z);
  138. e[i].l=x,e[i].r=y,e[i].v=z;
  139. }
  140. //kruscal();
  141. spfa(S);
  142. //diji(S);
  143. return 0;
  144. }

dijisktra(这个比较好)

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <stack>
  9. #define ll long long
  10. using namespace std;
  11. const int inf=0x3f3f3f3f;
  12. const ll INF=0x3f3f3f3f3f3f3f3fll;
  13. struct Edge
  14. {
  15. int nxt;
  16. int to;
  17. ll val;
  18. }edge[1000005];
  19. struct E
  20. {
  21. int l,r;
  22. ll v;
  23. friend bool operator < (E a,E b)
  24. {
  25. return a.v<b.v;
  26. }
  27. }e[500005];
  28. struct node
  29. {
  30. int p;ll v;
  31. node (){}
  32. node (int x,ll y):p(x),v(y){}
  33. friend bool operator < (node a,node b)
  34. {
  35. return a.v>b.v;
  36. }
  37. };
  38. int f[200005];
  39. int head[200005];
  40. ll dis[200005];
  41. bool used[200005];
  42. int cnt=1;
  43. int n,m,S,T;
  44. void init()
  45. {
  46. for(int i=1;i<=n;i++)f[i]=i,head[i]=0;
  47. cnt=1;
  48. }
  49. void add(int l,int r,ll w)
  50. {
  51. edge[cnt].nxt=head[l];
  52. edge[cnt].to=r;
  53. edge[cnt].val=w;
  54. head[l]=cnt++;
  55. }
  56. int findf(int x)
  57. {
  58. return x==f[x]?x:f[x]=findf(f[x]);
  59. }
  60. void kruscal()
  61. {
  62. sort(e+1,e+m+1);
  63. int tot=0;ll ret=0;
  64. for(int i=1;i<=m;i++)
  65. {
  66. int f1=findf(e[i].l),f2=findf(e[i].r);
  67. if(f1==f2)continue;
  68. f[f1]=f2,tot++,ret+=e[i].v;
  69. if(tot==n-1)break;
  70. }
  71. if(tot==n-1)printf("%lld\n",ret);
  72. else printf("orz\n");
  73. }
  74. void spfa(int st)
  75. {
  76. memset(dis,0x3f,sizeof(dis));
  77. dis[st]=0,used[st]=1;
  78. queue <int> M;
  79. M.push(st);
  80. while(!M.empty())
  81. {
  82. int u=M.front();
  83. M.pop();
  84. for(int i=head[u];i;i=edge[i].nxt)
  85. {
  86. int to=edge[i].to;
  87. if(dis[to]>dis[u]+edge[i].val)
  88. {
  89. dis[to]=dis[u]+edge[i].val;
  90. if(!used[to])used[to]=1,M.push(to);
  91. }
  92. }
  93. used[u]=0;
  94. }
  95. for(int i=1;i<=n;i++)
  96. {
  97. if(dis[i]==INF)printf("2147483647 ");
  98. else printf("%lld ",dis[i]);
  99. }
  100. }
  101. void diji(int st)
  102. {
  103. memset(dis,0x3f,sizeof(dis));
  104. dis[st]=0;
  105. priority_queue <node> M;
  106. M.push(node(st,0));
  107. while(!M.empty())
  108. {
  109. node temp=M.top();
  110. M.pop();
  111. int u=temp.p;
  112. if(used[u])continue;
  113. used[u]=1;
  114. for(int i=head[u];i;i=edge[i].nxt)
  115. {
  116. int to=edge[i].to;
  117. if(dis[to]>dis[u]+edge[i].val&&!used[to])dis[to]=dis[u]+edge[i].val,M.push(node(to,dis[to]));
  118. }
  119. }
  120. for(int i=1;i<=n;i++)printf("%lld ",dis[i]);
  121. }
  122. template <typename T>inline void read(T &x)
  123. {
  124. T f=1,c=0;char ch=getchar();
  125. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  126. while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
  127. x=c*f;
  128. }
  129. int main()
  130. {
  131. read(n),read(m),read(S);
  132. init();
  133. for(int i=1;i<=m;i++)
  134. {
  135. int x,y;ll z;
  136. read(x),read(y),read(z);
  137. add(x,y,z);//,add(y,x,z);
  138. e[i].l=x,e[i].r=y,e[i].v=z;
  139. }
  140. //kruscal();
  141. //spfa(S);
  142. diji(S);
  143. return 0;
  144. }

3.LCA

倍增版本:

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <stack>
  9. #define ll long long
  10. using namespace std;
  11. const int inf=0x3f3f3f3f;
  12. const ll INF=0x3f3f3f3f3f3f3f3fll;
  13. struct Edge
  14. {
  15. int nxt;
  16. int to;
  17. ll val;
  18. }edge[5000005];
  19. struct E
  20. {
  21. int l,r;
  22. ll v;
  23. friend bool operator < (E a,E b)
  24. {
  25. return a.v<b.v;
  26. }
  27. }e[5000005];
  28. struct node
  29. {
  30. int p;ll v;
  31. node (){}
  32. node (int x,ll y):p(x),v(y){}
  33. friend bool operator < (node a,node b)
  34. {
  35. return a.v>b.v;
  36. }
  37. };
  38. int f[500005];
  39. int head[500005];
  40. ll dis[500005];
  41. int fa[500005][25];
  42. int dep[500005];
  43. int siz[500005],son[500005],ttop[500005];
  44. bool used[500005];
  45. int cnt=1;
  46. int n,m,S,T;
  47. void init()
  48. {
  49. for(int i=1;i<=n;i++)f[i]=i,head[i]=0;
  50. cnt=1;
  51. }
  52. void add(int l,int r,ll w)
  53. {
  54. edge[cnt].nxt=head[l];
  55. edge[cnt].to=r;
  56. edge[cnt].val=w;
  57. head[l]=cnt++;
  58. }
  59. int findf(int x)
  60. {
  61. return x==f[x]?x:f[x]=findf(f[x]);
  62. }
  63. void tree_dfs(int x,int fx)
  64. {
  65. dep[x]=dep[fx]+1,siz[x]=1,fa[x][0]=fx;
  66. for(int i=1;i<=20;i++)fa[x][i]=fa[fa[x][i-1]][i-1];
  67. for(int i=head[x];i;i=edge[i].nxt)
  68. {
  69. int to=edge[i].to;
  70. if(to==fx)continue;
  71. tree_dfs(to,x);
  72. siz[x]+=siz[to],son[x]=(siz[son[x]]>siz[to])?son[x]:to;
  73. }
  74. }
  75. void tree_redfs(int x,int topx,int fx)
  76. {
  77. ttop[x]=topx;
  78. if(son[x])tree_redfs(son[x],topx,x);
  79. for(int i=head[x];i;i=edge[i].nxt)
  80. {
  81. int to=edge[i].to;
  82. if(to==fx||to==son[x])continue;
  83. tree_redfs(to,to,x);
  84. }
  85. }
  86. int quick_jump_LCA(int x,int y)//倍增LCA
  87. {
  88. if(dep[x]>dep[y])swap(x,y);
  89. for(int i=20;i>=0;i--)if(dep[fa[y][i]]>=dep[x])y=fa[y][i];
  90. if(x==y)return x;
  91. int ret;
  92. for(int i=20;i>=0;i--)
  93. {
  94. if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
  95. else ret=fa[x][i];
  96. }
  97. return ret;
  98. }
  99. int link_cut_LCA(int x,int y)//树剖LCA
  100. {
  101. while(ttop[x]!=ttop[y])
  102. {
  103. if(dep[ttop[x]]<dep[ttop[y]])swap(x,y);
  104. x=fa[ttop[x]][0];
  105. }
  106. return dep[x]<dep[y]?x:y;
  107. }
  108. void kruscal()
  109. {
  110. sort(e+1,e+m+1);
  111. int tot=0;ll ret=0;
  112. for(int i=1;i<=m;i++)
  113. {
  114. int f1=findf(e[i].l),f2=findf(e[i].r);
  115. if(f1==f2)continue;
  116. f[f1]=f2,tot++,ret+=e[i].v;
  117. if(tot==n-1)break;
  118. }
  119. if(tot==n-1)printf("%lld\n",ret);
  120. else printf("orz\n");
  121. }
  122. void spfa(int st)
  123. {
  124. memset(dis,0x3f,sizeof(dis));
  125. dis[st]=0,used[st]=1;
  126. queue <int> M;
  127. M.push(st);
  128. while(!M.empty())
  129. {
  130. int u=M.front();
  131. M.pop();
  132. for(int i=head[u];i;i=edge[i].nxt)
  133. {
  134. int to=edge[i].to;
  135. if(dis[to]>dis[u]+edge[i].val)
  136. {
  137. dis[to]=dis[u]+edge[i].val;
  138. if(!used[to])used[to]=1,M.push(to);
  139. }
  140. }
  141. used[u]=0;
  142. }
  143. for(int i=1;i<=n;i++)
  144. {
  145. if(dis[i]==INF)printf("2147483647 ");
  146. else printf("%lld ",dis[i]);
  147. }
  148. }
  149. void diji(int st)
  150. {
  151. memset(dis,0x3f,sizeof(dis));
  152. dis[st]=0;
  153. priority_queue <node> M;
  154. M.push(node(st,0));
  155. while(!M.empty())
  156. {
  157. node temp=M.top();
  158. M.pop();
  159. int u=temp.p;
  160. if(used[u])continue;
  161. used[u]=1;
  162. for(int i=head[u];i;i=edge[i].nxt)
  163. {
  164. int to=edge[i].to;
  165. if(dis[to]>dis[u]+edge[i].val&&!used[to])dis[to]=dis[u]+edge[i].val,M.push(node(to,dis[to]));
  166. }
  167. }
  168. for(int i=1;i<=n;i++)printf("%lld ",dis[i]);
  169. }
  170. template <typename T>inline void read(T &x)
  171. {
  172. T f=1,c=0;char ch=getchar();
  173. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  174. while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
  175. x=c*f;
  176. }
  177. int main()
  178. {
  179. read(n),read(m),read(S);
  180. init();
  181. for(int i=1;i<n;i++)
  182. {
  183. int x,y;ll z;
  184. read(x),read(y);//,read(z);
  185. add(x,y,z),add(y,x,z);//,add(y,x,z);
  186. e[i].l=x,e[i].r=y,e[i].v=z;
  187. }
  188. //kruscal();
  189. //spfa(S);
  190. //diji(S);
  191. tree_dfs(S,S);//,tree_redfs(S,S,S);
  192. for(int i=1;i<=m;i++)
  193. {
  194. int x,y;
  195. read(x),read(y);
  196. printf("%d\n",quick_jump_LCA(x,y));
  197. }
  198. return 0;
  199. }

树剖版本:

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <stack>
  9. #define ll long long
  10. using namespace std;
  11. const int inf=0x3f3f3f3f;
  12. const ll INF=0x3f3f3f3f3f3f3f3fll;
  13. struct Edge
  14. {
  15. int nxt;
  16. int to;
  17. ll val;
  18. }edge[5000005];
  19. struct E
  20. {
  21. int l,r;
  22. ll v;
  23. friend bool operator < (E a,E b)
  24. {
  25. return a.v<b.v;
  26. }
  27. }e[5000005];
  28. struct node
  29. {
  30. int p;ll v;
  31. node (){}
  32. node (int x,ll y):p(x),v(y){}
  33. friend bool operator < (node a,node b)
  34. {
  35. return a.v>b.v;
  36. }
  37. };
  38. int f[500005];
  39. int head[500005];
  40. ll dis[500005];
  41. int fa[500005][25];
  42. int dep[500005];
  43. int siz[500005],son[500005],ttop[500005];
  44. bool used[500005];
  45. int cnt=1;
  46. int n,m,S,T;
  47. void init()
  48. {
  49. for(int i=1;i<=n;i++)f[i]=i,head[i]=0;
  50. cnt=1;
  51. }
  52. void add(int l,int r,ll w)
  53. {
  54. edge[cnt].nxt=head[l];
  55. edge[cnt].to=r;
  56. edge[cnt].val=w;
  57. head[l]=cnt++;
  58. }
  59. int findf(int x)
  60. {
  61. return x==f[x]?x:f[x]=findf(f[x]);
  62. }
  63. void tree_dfs(int x,int fx)
  64. {
  65. dep[x]=dep[fx]+1,siz[x]=1,fa[x][0]=fx;
  66. for(int i=1;i<=20;i++)fa[x][i]=fa[fa[x][i-1]][i-1];
  67. for(int i=head[x];i;i=edge[i].nxt)
  68. {
  69. int to=edge[i].to;
  70. if(to==fx)continue;
  71. tree_dfs(to,x);
  72. siz[x]+=siz[to],son[x]=(siz[son[x]]>siz[to])?son[x]:to;
  73. }
  74. }
  75. void tree_redfs(int x,int topx,int fx)
  76. {
  77. ttop[x]=topx;
  78. if(son[x])tree_redfs(son[x],topx,x);
  79. for(int i=head[x];i;i=edge[i].nxt)
  80. {
  81. int to=edge[i].to;
  82. if(to==fx||to==son[x])continue;
  83. tree_redfs(to,to,x);
  84. }
  85. }
  86. int quick_jump_LCA(int x,int y)//倍增LCA
  87. {
  88. if(dep[x]>dep[y])swap(x,y);
  89. for(int i=20;i>=0;i--)if(dep[fa[y][i]]>=dep[x])y=fa[y][i];
  90. if(x==y)return x;
  91. int ret;
  92. for(int i=20;i>=0;i--)
  93. {
  94. if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
  95. else ret=fa[x][i];
  96. }
  97. return ret;
  98. }
  99. int link_cut_LCA(int x,int y)//树剖LCA
  100. {
  101. while(ttop[x]!=ttop[y])
  102. {
  103. if(dep[ttop[x]]<dep[ttop[y]])swap(x,y);
  104. x=fa[ttop[x]][0];
  105. }
  106. return dep[x]<dep[y]?x:y;
  107. }
  108. void kruscal()
  109. {
  110. sort(e+1,e+m+1);
  111. int tot=0;ll ret=0;
  112. for(int i=1;i<=m;i++)
  113. {
  114. int f1=findf(e[i].l),f2=findf(e[i].r);
  115. if(f1==f2)continue;
  116. f[f1]=f2,tot++,ret+=e[i].v;
  117. if(tot==n-1)break;
  118. }
  119. if(tot==n-1)printf("%lld\n",ret);
  120. else printf("orz\n");
  121. }
  122. void spfa(int st)
  123. {
  124. memset(dis,0x3f,sizeof(dis));
  125. dis[st]=0,used[st]=1;
  126. queue <int> M;
  127. M.push(st);
  128. while(!M.empty())
  129. {
  130. int u=M.front();
  131. M.pop();
  132. for(int i=head[u];i;i=edge[i].nxt)
  133. {
  134. int to=edge[i].to;
  135. if(dis[to]>dis[u]+edge[i].val)
  136. {
  137. dis[to]=dis[u]+edge[i].val;
  138. if(!used[to])used[to]=1,M.push(to);
  139. }
  140. }
  141. used[u]=0;
  142. }
  143. for(int i=1;i<=n;i++)
  144. {
  145. if(dis[i]==INF)printf("2147483647 ");
  146. else printf("%lld ",dis[i]);
  147. }
  148. }
  149. void diji(int st)
  150. {
  151. memset(dis,0x3f,sizeof(dis));
  152. dis[st]=0;
  153. priority_queue <node> M;
  154. M.push(node(st,0));
  155. while(!M.empty())
  156. {
  157. node temp=M.top();
  158. M.pop();
  159. int u=temp.p;
  160. if(used[u])continue;
  161. used[u]=1;
  162. for(int i=head[u];i;i=edge[i].nxt)
  163. {
  164. int to=edge[i].to;
  165. if(dis[to]>dis[u]+edge[i].val&&!used[to])dis[to]=dis[u]+edge[i].val,M.push(node(to,dis[to]));
  166. }
  167. }
  168. for(int i=1;i<=n;i++)printf("%lld ",dis[i]);
  169. }
  170. template <typename T>inline void read(T &x)
  171. {
  172. T f=1,c=0;char ch=getchar();
  173. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  174. while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
  175. x=c*f;
  176. }
  177. int main()
  178. {
  179. read(n),read(m),read(S);
  180. init();
  181. for(int i=1;i<n;i++)
  182. {
  183. int x,y;ll z;
  184. read(x),read(y);//,read(z);
  185. add(x,y,z),add(y,x,z);//,add(y,x,z);
  186. e[i].l=x,e[i].r=y,e[i].v=z;
  187. }
  188. //kruscal();
  189. //spfa(S);
  190. //diji(S);
  191. tree_dfs(S,S),tree_redfs(S,S,S);
  192. for(int i=1;i<=m;i++)
  193. {
  194. int x,y;
  195. read(x),read(y);
  196. printf("%d\n",link_cut_LCA(x,y));
  197. }
  198. return 0;
  199. }

4.tarjan

有向图tarjan缩点+spfa最长路

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <stack>
  9. #include <vector>
  10. #define ll long long
  11. using namespace std;
  12. template <typename T>inline void read(T &x)
  13. {
  14. T f=1,c=0;char ch=getchar();
  15. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  16. while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
  17. x=c*f;
  18. }
  19. const int inf=0x3f3f3f3f;
  20. const ll INF=0x3f3f3f3f3f3f3f3fll;
  21. struct Edge
  22. {
  23. int nxt;
  24. int to;
  25. ll val;
  26. }edge[5000005];
  27. struct E
  28. {
  29. int l,r;
  30. ll v;
  31. friend bool operator < (E a,E b)
  32. {
  33. return a.v<b.v;
  34. }
  35. }e[5000005];
  36. struct node
  37. {
  38. int p;ll v;
  39. node (){}
  40. node (int x,ll y):p(x),v(y){}
  41. friend bool operator < (node a,node b)
  42. {
  43. return a.v>b.v;
  44. }
  45. };
  46. int f[500005];
  47. int head[500005];
  48. ll dis[500005];
  49. ll va[500005];
  50. int dfn[500005],low[500005],posi[500005];
  51. ll src_num[500005],src_cnt;
  52. int my_stack[500005],top=0;
  53. int fa[500005][25];
  54. int dep[500005];
  55. int spe[500005],nu;
  56. int siz[500005],son[500005],ttop[500005];
  57. bool used[500005];
  58. int cnt=1,deep;
  59. int n,m,S,T;
  60. vector <int> v[500005];
  61. void init()
  62. {
  63. for(int i=1;i<=n;i++)f[i]=i,head[i]=0;
  64. cnt=1;
  65. }
  66. void add(int l,int r,ll w)
  67. {
  68. edge[cnt].nxt=head[l];
  69. edge[cnt].to=r;
  70. edge[cnt].val=w;
  71. head[l]=cnt++;
  72. }
  73. int findf(int x)
  74. {
  75. return x==f[x]?x:f[x]=findf(f[x]);
  76. }
  77. void tree_dfs(int x,int fx)
  78. {
  79. dep[x]=dep[fx]+1,siz[x]=1,fa[x][0]=fx;
  80. for(int i=1;i<=20;i++)fa[x][i]=fa[fa[x][i-1]][i-1];
  81. for(int i=head[x];i;i=edge[i].nxt)
  82. {
  83. int to=edge[i].to;
  84. if(to==fx)continue;
  85. tree_dfs(to,x);
  86. siz[x]+=siz[to],son[x]=(siz[son[x]]>siz[to])?son[x]:to;
  87. }
  88. }
  89. void tree_redfs(int x,int topx,int fx)
  90. {
  91. ttop[x]=topx;
  92. if(son[x])tree_redfs(son[x],topx,x);
  93. for(int i=head[x];i;i=edge[i].nxt)
  94. {
  95. int to=edge[i].to;
  96. if(to==fx||to==son[x])continue;
  97. tree_redfs(to,to,x);
  98. }
  99. }
  100. int quick_jump_LCA(int x,int y)//倍增LCA
  101. {
  102. if(dep[x]>dep[y])swap(x,y);
  103. for(int i=20;i>=0;i--)if(dep[fa[y][i]]>=dep[x])y=fa[y][i];
  104. if(x==y)return x;
  105. int ret;
  106. for(int i=20;i>=0;i--)
  107. {
  108. if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
  109. else ret=fa[x][i];
  110. }
  111. return ret;
  112. }
  113. int link_cut_LCA(int x,int y)//树剖LCA
  114. {
  115. while(ttop[x]!=ttop[y])
  116. {
  117. if(dep[ttop[x]]<dep[ttop[y]])swap(x,y);
  118. x=fa[ttop[x]][0];
  119. }
  120. return dep[x]<dep[y]?x:y;
  121. }
  122. void tarjan(int x)
  123. {
  124. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  125. for(int i=head[x];i;i=edge[i].nxt)
  126. {
  127. int to=edge[i].to;
  128. if(!dfn[to])
  129. {
  130. tarjan(to);
  131. low[x]=min(low[x],low[to]);
  132. }else if(!posi[to])low[x]=min(low[x],dfn[to]);
  133. }
  134. if(dfn[x]==low[x])
  135. {
  136. src_cnt++;
  137. int t=0;
  138. while(t!=x)
  139. {
  140. t=my_stack[top--];
  141. src_num[src_cnt]+=va[t];
  142. posi[t]=src_cnt;
  143. }
  144. }
  145. }
  146. void kruscal()
  147. {
  148. sort(e+1,e+m+1);
  149. int tot=0;ll ret=0;
  150. for(int i=1;i<=m;i++)
  151. {
  152. int f1=findf(e[i].l),f2=findf(e[i].r);
  153. if(f1==f2)continue;
  154. f[f1]=f2,tot++,ret+=e[i].v;
  155. if(tot==n-1)break;
  156. }
  157. if(tot==n-1)printf("%lld\n",ret);
  158. else printf("orz\n");
  159. }
  160. void min_dis_spfa(int st)
  161. {
  162. memset(dis,0x3f,sizeof(dis));
  163. dis[st]=0,used[st]=1;
  164. queue <int> M;
  165. M.push(st);
  166. while(!M.empty())
  167. {
  168. int u=M.front();
  169. M.pop();
  170. for(int i=head[u];i;i=edge[i].nxt)
  171. {
  172. int to=edge[i].to;
  173. if(dis[to]>dis[u]+edge[i].val)
  174. {
  175. dis[to]=dis[u]+edge[i].val;
  176. if(!used[to])used[to]=1,M.push(to);
  177. }
  178. }
  179. used[u]=0;
  180. }
  181. for(int i=1;i<=n;i++)
  182. {
  183. if(dis[i]==INF)printf("2147483647 ");
  184. else printf("%lld ",dis[i]);
  185. }
  186. }
  187. void diji(int st)
  188. {
  189. memset(dis,0x3f,sizeof(dis));
  190. dis[st]=0;
  191. priority_queue <node> M;
  192. M.push(node(st,0));
  193. while(!M.empty())
  194. {
  195. node temp=M.top();
  196. M.pop();
  197. int u=temp.p;
  198. if(used[u])continue;
  199. used[u]=1;
  200. for(int i=head[u];i;i=edge[i].nxt)
  201. {
  202. int to=edge[i].to;
  203. if(dis[to]>dis[u]+edge[i].val&&!used[to])dis[to]=dis[u]+edge[i].val,M.push(node(to,dis[to]));
  204. }
  205. }
  206. for(int i=1;i<=n;i++)printf("%lld ",dis[i]);
  207. }
  208. void max_dis_spfa(int st)
  209. {
  210. memset(dis,0,sizeof(dis));
  211. used[st]=1;
  212. dis[st]=src_num[st];
  213. queue <int> M;
  214. M.push(st);
  215. while(!M.empty())
  216. {
  217. int u=M.front();
  218. M.pop();
  219. for(int i=0;i<v[u].size();i++)
  220. {
  221. int to=v[u][i];
  222. if(dis[to]<dis[u]+src_num[to])
  223. {
  224. dis[to]=dis[u]+src_num[to];
  225. if(!used[to])used[to]=1,M.push(to);
  226. }
  227. }
  228. used[u]=0;
  229. }
  230. ll ans=0;
  231. for(int i=1;i<=nu;i++)ans=max(ans,dis[posi[spe[i]]]);
  232. printf("%lld\n",ans);
  233. }
  234. void build_MST()
  235. {
  236. kruscal();
  237. }
  238. void get_min_dis_road()
  239. {
  240. //min_dis_spfa(S);
  241. diji(S);
  242. }
  243. void solve_LCA()
  244. {
  245. tree_dfs(S,S),tree_redfs(S,S,S);
  246. for(int i=1;i<=m;i++)
  247. {
  248. int x,y;
  249. read(x),read(y);
  250. printf("%d\n",link_cut_LCA(x,y));
  251. }
  252. }
  253. void direc_tarjan()//有向图tarjan
  254. {
  255. for(int i=1;i<=n;i++)read(va[i]);
  256. read(S),read(nu);
  257. for(int i=1;i<=nu;i++)read(spe[i]);
  258. for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
  259. for(int i=1;i<=n;i++)
  260. {
  261. for(int j=head[i];j;j=edge[j].nxt)
  262. {
  263. int to=edge[j].to;
  264. if(posi[i]==posi[to])continue;
  265. else v[posi[i]].push_back(posi[to]);
  266. }
  267. }
  268. max_dis_spfa(posi[S]);
  269. }
  270.  
  271. int main()
  272. {
  273. read(n),read(m);
  274. init();
  275. for(int i=1;i<=m;i++)
  276. {
  277. int x,y;ll z;
  278. read(x),read(y);//,read(z);
  279. add(x,y,z);//,add(y,x,z);
  280. e[i].l=x,e[i].r=y,e[i].v=z;
  281. }
  282. direc_tarjan();
  283. return 0;
  284. }

无向图割边:

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <stack>
  9. #include <vector>
  10. #define ll long long
  11. using namespace std;
  12. template <typename T>inline void read(T &x)
  13. {
  14. T f=1,c=0;char ch=getchar();
  15. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  16. while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
  17. x=c*f;
  18. }
  19. const int inf=0x3f3f3f3f;
  20. const ll INF=0x3f3f3f3f3f3f3f3fll;
  21. struct Edge
  22. {
  23. int nxt;
  24. int to;
  25. ll val;
  26. }edge[5000005];
  27. struct E
  28. {
  29. int l,r;
  30. ll v;
  31. friend bool operator < (E a,E b)
  32. {
  33. return a.v<b.v;
  34. }
  35. }e[5000005];
  36. struct node
  37. {
  38. int p;ll v;
  39. node (){}
  40. node (int x,ll y):p(x),v(y){}
  41. friend bool operator < (node a,node b)
  42. {
  43. return a.v>b.v;
  44. }
  45. };
  46. int f[500005];
  47. int head[500005];
  48. ll dis[500005];
  49. ll va[500005];
  50. int dfn[500005],low[500005],posi[500005];
  51. ll src_num[500005],src_cnt;
  52. int my_stack[500005],top=0;
  53. int fa[500005][25];
  54. int dep[500005];
  55. int spe[500005],nu;
  56. int siz[500005],son[500005],ttop[500005];
  57. int inr[500005],our[500005];
  58. bool used[500005];
  59. int cnt=1,deep;
  60. int count_cut_line;
  61. int n,m,S,T;
  62. vector <int> v[500005];
  63. void init()
  64. {
  65. for(int i=1;i<=n;i++)f[i]=i,head[i]=0;
  66. cnt=1;
  67. }
  68. void add(int l,int r,ll w)
  69. {
  70. edge[cnt].nxt=head[l];
  71. edge[cnt].to=r;
  72. edge[cnt].val=w;
  73. head[l]=cnt++;
  74. }
  75. int findf(int x)
  76. {
  77. return x==f[x]?x:f[x]=findf(f[x]);
  78. }
  79. void tree_dfs(int x,int fx)
  80. {
  81. dep[x]=dep[fx]+1,siz[x]=1,fa[x][0]=fx;
  82. for(int i=1;i<=20;i++)fa[x][i]=fa[fa[x][i-1]][i-1];
  83. for(int i=head[x];i;i=edge[i].nxt)
  84. {
  85. int to=edge[i].to;
  86. if(to==fx)continue;
  87. tree_dfs(to,x);
  88. siz[x]+=siz[to],son[x]=(siz[son[x]]>siz[to])?son[x]:to;
  89. }
  90. }
  91. void tree_redfs(int x,int topx,int fx)
  92. {
  93. ttop[x]=topx;
  94. if(son[x])tree_redfs(son[x],topx,x);
  95. for(int i=head[x];i;i=edge[i].nxt)
  96. {
  97. int to=edge[i].to;
  98. if(to==fx||to==son[x])continue;
  99. tree_redfs(to,to,x);
  100. }
  101. }
  102. int quick_jump_LCA(int x,int y)//倍增LCA
  103. {
  104. if(dep[x]>dep[y])swap(x,y);
  105. for(int i=20;i>=0;i--)if(dep[fa[y][i]]>=dep[x])y=fa[y][i];
  106. if(x==y)return x;
  107. int ret;
  108. for(int i=20;i>=0;i--)
  109. {
  110. if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
  111. else ret=fa[x][i];
  112. }
  113. return ret;
  114. }
  115. int link_cut_LCA(int x,int y)//树剖LCA
  116. {
  117. while(ttop[x]!=ttop[y])
  118. {
  119. if(dep[ttop[x]]<dep[ttop[y]])swap(x,y);
  120. x=fa[ttop[x]][0];
  121. }
  122. return dep[x]<dep[y]?x:y;
  123. }
  124. void di_tarjan(int x)
  125. {
  126. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  127. for(int i=head[x];i;i=edge[i].nxt)
  128. {
  129. int to=edge[i].to;
  130. if(!dfn[to])
  131. {
  132. di_tarjan(to);
  133. low[x]=min(low[x],low[to]);
  134. }else if(!posi[to])low[x]=min(low[x],dfn[to]);
  135. }
  136. if(dfn[x]==low[x])
  137. {
  138. src_cnt++;
  139. int t=0;
  140. while(t!=x)
  141. {
  142. t=my_stack[top--];
  143. src_num[src_cnt]+=va[t];
  144. posi[t]=src_cnt;
  145. }
  146. }
  147. }
  148. void ed_tarjan(int x,int fx)
  149. {
  150. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  151. for(int i=head[x];i;i=edge[i].nxt)
  152. {
  153. int to=edge[i].to;
  154. if(edge[i].val==fx)continue;
  155. if(!dfn[to])
  156. {
  157. ed_tarjan(to,edge[i].val);
  158. low[x]=min(low[x],low[to]);
  159. if(dfn[x]<low[to])count_cut_line++;
  160. }else if(!posi[to])low[x]=min(low[x],dfn[to]);
  161. }
  162. if(dfn[x]==low[x])
  163. {
  164. src_cnt++;
  165. int t=0;
  166. while(t!=x)
  167. {
  168. t=my_stack[top--];
  169. src_num[src_cnt]++;
  170. posi[t]=src_cnt;
  171. }
  172. }
  173. }
  174. void kruscal()
  175. {
  176. sort(e+1,e+m+1);
  177. int tot=0;ll ret=0;
  178. for(int i=1;i<=m;i++)
  179. {
  180. int f1=findf(e[i].l),f2=findf(e[i].r);
  181. if(f1==f2)continue;
  182. f[f1]=f2,tot++,ret+=e[i].v;
  183. if(tot==n-1)break;
  184. }
  185. if(tot==n-1)printf("%lld\n",ret);
  186. else printf("orz\n");
  187. }
  188. void min_dis_spfa(int st)
  189. {
  190. memset(dis,0x3f,sizeof(dis));
  191. dis[st]=0,used[st]=1;
  192. queue <int> M;
  193. M.push(st);
  194. while(!M.empty())
  195. {
  196. int u=M.front();
  197. M.pop();
  198. for(int i=head[u];i;i=edge[i].nxt)
  199. {
  200. int to=edge[i].to;
  201. if(dis[to]>dis[u]+edge[i].val)
  202. {
  203. dis[to]=dis[u]+edge[i].val;
  204. if(!used[to])used[to]=1,M.push(to);
  205. }
  206. }
  207. used[u]=0;
  208. }
  209. for(int i=1;i<=n;i++)
  210. {
  211. if(dis[i]==INF)printf("2147483647 ");
  212. else printf("%lld ",dis[i]);
  213. }
  214. }
  215. void diji(int st)
  216. {
  217. memset(dis,0x3f,sizeof(dis));
  218. dis[st]=0;
  219. priority_queue <node> M;
  220. M.push(node(st,0));
  221. while(!M.empty())
  222. {
  223. node temp=M.top();
  224. M.pop();
  225. int u=temp.p;
  226. if(used[u])continue;
  227. used[u]=1;
  228. for(int i=head[u];i;i=edge[i].nxt)
  229. {
  230. int to=edge[i].to;
  231. if(dis[to]>dis[u]+edge[i].val&&!used[to])dis[to]=dis[u]+edge[i].val,M.push(node(to,dis[to]));
  232. }
  233. }
  234. for(int i=1;i<=n;i++)printf("%lld ",dis[i]);
  235. }
  236. void max_dis_spfa(int st)
  237. {
  238. memset(dis,0,sizeof(dis));
  239. used[st]=1;
  240. dis[st]=src_num[st];
  241. queue <int> M;
  242. M.push(st);
  243. while(!M.empty())
  244. {
  245. int u=M.front();
  246. M.pop();
  247. for(int i=0;i<v[u].size();i++)
  248. {
  249. int to=v[u][i];
  250. if(dis[to]<dis[u]+src_num[to])
  251. {
  252. dis[to]=dis[u]+src_num[to];
  253. if(!used[to])used[to]=1,M.push(to);
  254. }
  255. }
  256. used[u]=0;
  257. }
  258. ll ans=0;
  259. for(int i=1;i<=nu;i++)ans=max(ans,dis[posi[spe[i]]]);
  260. printf("%lld\n",ans);
  261. }
  262. void build_MST()
  263. {
  264. kruscal();
  265. }
  266. void get_min_dis_road()
  267. {
  268. //min_dis_spfa(S);
  269. diji(S);
  270. }
  271. void solve_LCA()
  272. {
  273. tree_dfs(S,S),tree_redfs(S,S,S);
  274. for(int i=1;i<=m;i++)
  275. {
  276. int x,y;
  277. read(x),read(y);
  278. printf("%d\n",link_cut_LCA(x,y));
  279. }
  280. }
  281. void direc_tarjan()//有向图tarjan
  282. {
  283. for(int i=1;i<=n;i++)read(va[i]);
  284. read(S),read(nu);
  285. for(int i=1;i<=nu;i++)read(spe[i]);
  286. for(int i=1;i<=n;i++)if(!dfn[i])di_tarjan(i);
  287. for(int i=1;i<=n;i++)
  288. {
  289. for(int j=head[i];j;j=edge[j].nxt)
  290. {
  291. int to=edge[j].to;
  292. if(posi[i]==posi[to])continue;
  293. else v[posi[i]].push_back(posi[to]);
  294. }
  295. }
  296. max_dis_spfa(posi[S]);
  297. }
  298. void cut_line_tarjan()
  299. {
  300. for(int i=1;i<=n;i++)if(!dfn[i])ed_tarjan(i,-1);
  301. printf("%d ",count_cut_line);
  302. for(int i=1;i<=n;i++)
  303. {
  304. for(int j=head[i];j;j=edge[j].nxt)
  305. {
  306. int to=edge[j].to;
  307. if(posi[i]!=posi[to])inr[posi[to]]++;
  308. }
  309. }
  310. int s=0;
  311. for(int i=1;i<=src_cnt;i++)if(inr[i]==1)s++;
  312. printf("%d\n",(s+1)>>1);
  313. }
  314. int main()
  315. {
  316. read(n),read(m);
  317. init();
  318. for(int i=1;i<=m;i++)
  319. {
  320. int x,y;ll z=i;
  321. read(x),read(y);//,read(z);
  322. add(x,y,z),add(y,x,z);
  323. e[i].l=x,e[i].r=y,e[i].v=z;
  324. }
  325. cut_line_tarjan();
  326. return 0;
  327. }

无向图割点:

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <stack>
  9. #include <vector>
  10. #define ll long long
  11. using namespace std;
  12. template <typename T>inline void read(T &x)
  13. {
  14. T f=1,c=0;char ch=getchar();
  15. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  16. while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
  17. x=c*f;
  18. }
  19. const int inf=0x3f3f3f3f;
  20. const ll INF=0x3f3f3f3f3f3f3f3fll;
  21. struct Edge
  22. {
  23. int nxt;
  24. int to;
  25. ll val;
  26. }edge[5000005];
  27. struct E
  28. {
  29. int l,r;
  30. ll v;
  31. friend bool operator < (E a,E b)
  32. {
  33. return a.v<b.v;
  34. }
  35. }e[5000005];
  36. struct node
  37. {
  38. int p;ll v;
  39. node (){}
  40. node (int x,ll y):p(x),v(y){}
  41. friend bool operator < (node a,node b)
  42. {
  43. return a.v>b.v;
  44. }
  45. };
  46. int f[500005];
  47. int head[500005];
  48. ll dis[500005];
  49. ll va[500005];
  50. int dfn[500005],low[500005],posi[500005];
  51. ll src_num[500005],src_cnt;
  52. int my_stack[500005],top=0;
  53. int fa[500005][25];
  54. int dep[500005];
  55. int spe[500005],nu;
  56. int siz[500005],son[500005],ttop[500005];
  57. int inr[500005],our[500005];
  58. bool used[500005];
  59. int cnt=1,deep;
  60. int count_cut_line;
  61. int n,m,S,T;
  62. vector <int> v[500005];
  63. vector <int> peo[500005];
  64. vector <int> cut_point;
  65. bool cmp(vector <int> a,vector <int> b)
  66. {
  67. int lim=min(a.size(),b.size());
  68. for(int i=0;i<lim;i++)if(a[i]!=b[i])return a[i]<b[i];
  69. return a.size()<b.size();
  70. }
  71. void init()
  72. {
  73. for(int i=1;i<=n;i++)f[i]=i,head[i]=0;
  74. cnt=1;
  75. }
  76. void add(int l,int r,ll w)
  77. {
  78. edge[cnt].nxt=head[l];
  79. edge[cnt].to=r;
  80. edge[cnt].val=w;
  81. head[l]=cnt++;
  82. }
  83. int findf(int x)
  84. {
  85. return x==f[x]?x:f[x]=findf(f[x]);
  86. }
  87. void tree_dfs(int x,int fx)
  88. {
  89. dep[x]=dep[fx]+1,siz[x]=1,fa[x][0]=fx;
  90. for(int i=1;i<=20;i++)fa[x][i]=fa[fa[x][i-1]][i-1];
  91. for(int i=head[x];i;i=edge[i].nxt)
  92. {
  93. int to=edge[i].to;
  94. if(to==fx)continue;
  95. tree_dfs(to,x);
  96. siz[x]+=siz[to],son[x]=(siz[son[x]]>siz[to])?son[x]:to;
  97. }
  98. }
  99. void tree_redfs(int x,int topx,int fx)
  100. {
  101. ttop[x]=topx;
  102. if(son[x])tree_redfs(son[x],topx,x);
  103. for(int i=head[x];i;i=edge[i].nxt)
  104. {
  105. int to=edge[i].to;
  106. if(to==fx||to==son[x])continue;
  107. tree_redfs(to,to,x);
  108. }
  109. }
  110. int quick_jump_LCA(int x,int y)//倍增LCA
  111. {
  112. if(dep[x]>dep[y])swap(x,y);
  113. for(int i=20;i>=0;i--)if(dep[fa[y][i]]>=dep[x])y=fa[y][i];
  114. if(x==y)return x;
  115. int ret;
  116. for(int i=20;i>=0;i--)
  117. {
  118. if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
  119. else ret=fa[x][i];
  120. }
  121. return ret;
  122. }
  123. int link_cut_LCA(int x,int y)//树剖LCA
  124. {
  125. while(ttop[x]!=ttop[y])
  126. {
  127. if(dep[ttop[x]]<dep[ttop[y]])swap(x,y);
  128. x=fa[ttop[x]][0];
  129. }
  130. return dep[x]<dep[y]?x:y;
  131. }
  132. void di_tarjan(int x)
  133. {
  134. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  135. for(int i=head[x];i;i=edge[i].nxt)
  136. {
  137. int to=edge[i].to;
  138. if(!dfn[to])
  139. {
  140. di_tarjan(to);
  141. low[x]=min(low[x],low[to]);
  142. }else if(!posi[to])low[x]=min(low[x],dfn[to]);
  143. }
  144. if(dfn[x]==low[x])
  145. {
  146. src_cnt++;
  147. int t=0;
  148. while(t!=x)
  149. {
  150. t=my_stack[top--];
  151. src_num[src_cnt]+=va[t];
  152. posi[t]=src_cnt;
  153. }
  154. }
  155. }
  156. void ed_tarjan(int x,int fx)
  157. {
  158. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  159. for(int i=head[x];i;i=edge[i].nxt)
  160. {
  161. int to=edge[i].to;
  162. if(edge[i].val==fx)continue;
  163. if(!dfn[to])
  164. {
  165. ed_tarjan(to,edge[i].val);
  166. low[x]=min(low[x],low[to]);
  167. if(dfn[x]<low[to])count_cut_line++;
  168. }else if(!posi[to])low[x]=min(low[x],dfn[to]);
  169. }
  170. if(dfn[x]==low[x])
  171. {
  172. src_cnt++;
  173. int t=0;
  174. while(t!=x)
  175. {
  176. t=my_stack[top--];
  177. src_num[src_cnt]++;
  178. posi[t]=src_cnt;
  179. }
  180. }
  181. }
  182. void po_tarjan(int x,int fx)
  183. {
  184. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  185. for(int i=head[x];i;i=edge[i].nxt)
  186. {
  187. int to=edge[i].to;
  188. if(to==fx)continue;
  189. if(!dfn[to])
  190. {
  191. int pre=top;
  192. po_tarjan(to,x);
  193. low[x]=min(low[x],low[to]);
  194. if(dfn[x]<=low[to])
  195. {
  196. src_cnt++,posi[x]++;
  197. int t=0;
  198. while(top!=pre)
  199. {
  200. t=my_stack[top--];
  201. peo[src_cnt].push_back(t);
  202. }
  203. peo[src_cnt].push_back(x);
  204. sort(peo[src_cnt].begin(),peo[src_cnt].end());
  205. }
  206. }else low[x]=min(low[x],dfn[to]);
  207. }
  208. }
  209. void kruscal()
  210. {
  211. sort(e+1,e+m+1);
  212. int tot=0;ll ret=0;
  213. for(int i=1;i<=m;i++)
  214. {
  215. int f1=findf(e[i].l),f2=findf(e[i].r);
  216. if(f1==f2)continue;
  217. f[f1]=f2,tot++,ret+=e[i].v;
  218. if(tot==n-1)break;
  219. }
  220. if(tot==n-1)printf("%lld\n",ret);
  221. else printf("orz\n");
  222. }
  223. void min_dis_spfa(int st)
  224. {
  225. memset(dis,0x3f,sizeof(dis));
  226. dis[st]=0,used[st]=1;
  227. queue <int> M;
  228. M.push(st);
  229. while(!M.empty())
  230. {
  231. int u=M.front();
  232. M.pop();
  233. for(int i=head[u];i;i=edge[i].nxt)
  234. {
  235. int to=edge[i].to;
  236. if(dis[to]>dis[u]+edge[i].val)
  237. {
  238. dis[to]=dis[u]+edge[i].val;
  239. if(!used[to])used[to]=1,M.push(to);
  240. }
  241. }
  242. used[u]=0;
  243. }
  244. for(int i=1;i<=n;i++)
  245. {
  246. if(dis[i]==INF)printf("2147483647 ");
  247. else printf("%lld ",dis[i]);
  248. }
  249. }
  250. void diji(int st)
  251. {
  252. memset(dis,0x3f,sizeof(dis));
  253. dis[st]=0;
  254. priority_queue <node> M;
  255. M.push(node(st,0));
  256. while(!M.empty())
  257. {
  258. node temp=M.top();
  259. M.pop();
  260. int u=temp.p;
  261. if(used[u])continue;
  262. used[u]=1;
  263. for(int i=head[u];i;i=edge[i].nxt)
  264. {
  265. int to=edge[i].to;
  266. if(dis[to]>dis[u]+edge[i].val&&!used[to])dis[to]=dis[u]+edge[i].val,M.push(node(to,dis[to]));
  267. }
  268. }
  269. for(int i=1;i<=n;i++)printf("%lld ",dis[i]);
  270. }
  271. void max_dis_spfa(int st)
  272. {
  273. memset(dis,0,sizeof(dis));
  274. used[st]=1;
  275. dis[st]=src_num[st];
  276. queue <int> M;
  277. M.push(st);
  278. while(!M.empty())
  279. {
  280. int u=M.front();
  281. M.pop();
  282. for(int i=0;i<v[u].size();i++)
  283. {
  284. int to=v[u][i];
  285. if(dis[to]<dis[u]+src_num[to])
  286. {
  287. dis[to]=dis[u]+src_num[to];
  288. if(!used[to])used[to]=1,M.push(to);
  289. }
  290. }
  291. used[u]=0;
  292. }
  293. ll ans=0;
  294. for(int i=1;i<=nu;i++)ans=max(ans,dis[posi[spe[i]]]);
  295. printf("%lld\n",ans);
  296. }
  297. void build_MST()
  298. {
  299. kruscal();
  300. }
  301. void get_min_dis_road()
  302. {
  303. //min_dis_spfa(S);
  304. diji(S);
  305. }
  306. void solve_LCA()
  307. {
  308. tree_dfs(S,S),tree_redfs(S,S,S);
  309. for(int i=1;i<=m;i++)
  310. {
  311. int x,y;
  312. read(x),read(y);
  313. printf("%d\n",link_cut_LCA(x,y));
  314. }
  315. }
  316. void direc_tarjan()//有向图tarjan
  317. {
  318. for(int i=1;i<=n;i++)read(va[i]);
  319. read(S),read(nu);
  320. for(int i=1;i<=nu;i++)read(spe[i]);
  321. for(int i=1;i<=n;i++)if(!dfn[i])di_tarjan(i);
  322. for(int i=1;i<=n;i++)
  323. {
  324. for(int j=head[i];j;j=edge[j].nxt)
  325. {
  326. int to=edge[j].to;
  327. if(posi[i]==posi[to])continue;
  328. else v[posi[i]].push_back(posi[to]);
  329. }
  330. }
  331. max_dis_spfa(posi[S]);
  332. }
  333. void cut_line_tarjan()
  334. {
  335. for(int i=1;i<=n;i++)if(!dfn[i])ed_tarjan(i,-1);
  336. printf("%d ",count_cut_line);
  337. for(int i=1;i<=n;i++)
  338. {
  339. for(int j=head[i];j;j=edge[j].nxt)
  340. {
  341. int to=edge[j].to;
  342. if(posi[i]!=posi[to])inr[posi[to]]++;
  343. }
  344. }
  345. int s=0;
  346. for(int i=1;i<=src_cnt;i++)if(inr[i]==1)s++;
  347. printf("%d\n",(s+1)>>1);
  348. }
  349. void cut_point_tarjan()
  350. {
  351. for(int i=1;i<=n;i++)if(!dfn[i])po_tarjan(i,-1),posi[i]--;
  352. for(int i=1;i<=n;i++)if(posi[i]>=1)cut_point.push_back(i);
  353. printf("%d\n",cut_point.size());
  354. for(int i=0;i<cut_point.size();i++)printf("%d ",cut_point[i]);
  355. printf("\n");
  356. printf("%d\n",src_cnt);
  357. sort(peo+1,peo+src_cnt+1,cmp);
  358. for(int i=1;i<=src_cnt;i++,printf("\n"))for(int j=0;j<peo[i].size();j++)printf("%d ",peo[i][j]);
  359. }
  360. int main()
  361. {
  362. read(n),read(m);
  363. init();
  364. for(int i=1;i<=m;i++)
  365. {
  366. int x,y;ll z=i;
  367. read(x),read(y);//,read(z);
  368. add(x,y,z),add(y,x,z);
  369. e[i].l=x,e[i].r=y,e[i].v=z;
  370. }
  371. cut_point_tarjan();
  372. return 0;
  373. }

5.网络流

最大流:

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <stack>
  9. #include <vector>
  10. #define ll long long
  11. using namespace std;
  12. template <typename T>inline void read(T &x)
  13. {
  14. T f=1,c=0;char ch=getchar();
  15. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  16. while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
  17. x=c*f;
  18. }
  19. const int inf=0x3f3f3f3f;
  20. const ll INF=0x3f3f3f3f3f3f3f3fll;
  21. struct Edge
  22. {
  23. int nxt;
  24. int to;
  25. ll val;
  26. ll pri;
  27. }edge[5000005];
  28. struct E
  29. {
  30. int l,r;
  31. ll v;
  32. friend bool operator < (E a,E b)
  33. {
  34. return a.v<b.v;
  35. }
  36. }e[5000005];
  37. struct node
  38. {
  39. int p;ll v;
  40. node (){}
  41. node (int x,ll y):p(x),v(y){}
  42. friend bool operator < (node a,node b)
  43. {
  44. return a.v>b.v;
  45. }
  46. };
  47. int f[500005];
  48. int head[500005];
  49. ll dis[500005];
  50. ll va[500005];
  51. int dfn[500005],low[500005],posi[500005];
  52. ll src_num[500005],src_cnt;
  53. int my_stack[500005],top=0;
  54. int fa[500005][25];
  55. int dep[500005];
  56. int spe[500005],nu;
  57. int siz[500005],son[500005],ttop[500005];
  58. int inr[500005],our[500005];
  59. int cur[500005];
  60. ll lim[500005];
  61. bool used[500005];
  62. int cnt=1,deep;
  63. int count_cut_line;
  64. int n,m,S,T;
  65. vector <int> v[500005];
  66. vector <int> peo[500005];
  67. vector <int> cut_point;
  68. bool cmp(vector <int> a,vector <int> b)
  69. {
  70. int lim=min(a.size(),b.size());
  71. for(int i=0;i<lim;i++)if(a[i]!=b[i])return a[i]<b[i];
  72. return a.size()<b.size();
  73. }
  74. void init()
  75. {
  76. for(int i=1;i<=n;i++)f[i]=i,head[i]=0;
  77. cnt=1;
  78. }
  79. void add(int l,int r,ll w)
  80. {
  81. edge[cnt].nxt=head[l];
  82. edge[cnt].to=r;
  83. edge[cnt].val=w;
  84. head[l]=cnt++;
  85. }
  86. void dadd(int l,int r,int w)
  87. {
  88. add(l,r,w),add(r,l,0);
  89. }
  90. int findf(int x)
  91. {
  92. return x==f[x]?x:f[x]=findf(f[x]);
  93. }
  94. void tree_dfs(int x,int fx)
  95. {
  96. dep[x]=dep[fx]+1,siz[x]=1,fa[x][0]=fx;
  97. for(int i=1;i<=20;i++)fa[x][i]=fa[fa[x][i-1]][i-1];
  98. for(int i=head[x];i;i=edge[i].nxt)
  99. {
  100. int to=edge[i].to;
  101. if(to==fx)continue;
  102. tree_dfs(to,x);
  103. siz[x]+=siz[to],son[x]=(siz[son[x]]>siz[to])?son[x]:to;
  104. }
  105. }
  106. void tree_redfs(int x,int topx,int fx)
  107. {
  108. ttop[x]=topx;
  109. if(son[x])tree_redfs(son[x],topx,x);
  110. for(int i=head[x];i;i=edge[i].nxt)
  111. {
  112. int to=edge[i].to;
  113. if(to==fx||to==son[x])continue;
  114. tree_redfs(to,to,x);
  115. }
  116. }
  117. int quick_jump_LCA(int x,int y)//倍增LCA
  118. {
  119. if(dep[x]>dep[y])swap(x,y);
  120. for(int i=20;i>=0;i--)if(dep[fa[y][i]]>=dep[x])y=fa[y][i];
  121. if(x==y)return x;
  122. int ret;
  123. for(int i=20;i>=0;i--)
  124. {
  125. if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
  126. else ret=fa[x][i];
  127. }
  128. return ret;
  129. }
  130. int link_cut_LCA(int x,int y)//树剖LCA
  131. {
  132. while(ttop[x]!=ttop[y])
  133. {
  134. if(dep[ttop[x]]<dep[ttop[y]])swap(x,y);
  135. x=fa[ttop[x]][0];
  136. }
  137. return dep[x]<dep[y]?x:y;
  138. }
  139. void di_tarjan(int x)
  140. {
  141. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  142. for(int i=head[x];i;i=edge[i].nxt)
  143. {
  144. int to=edge[i].to;
  145. if(!dfn[to])
  146. {
  147. di_tarjan(to);
  148. low[x]=min(low[x],low[to]);
  149. }else if(!posi[to])low[x]=min(low[x],dfn[to]);
  150. }
  151. if(dfn[x]==low[x])
  152. {
  153. src_cnt++;
  154. int t=0;
  155. while(t!=x)
  156. {
  157. t=my_stack[top--];
  158. src_num[src_cnt]+=va[t];
  159. posi[t]=src_cnt;
  160. }
  161. }
  162. }
  163. void ed_tarjan(int x,int fx)
  164. {
  165. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  166. for(int i=head[x];i;i=edge[i].nxt)
  167. {
  168. int to=edge[i].to;
  169. if(edge[i].val==fx)continue;
  170. if(!dfn[to])
  171. {
  172. ed_tarjan(to,edge[i].val);
  173. low[x]=min(low[x],low[to]);
  174. if(dfn[x]<low[to])count_cut_line++;
  175. }else if(!posi[to])low[x]=min(low[x],dfn[to]);
  176. }
  177. if(dfn[x]==low[x])
  178. {
  179. src_cnt++;
  180. int t=0;
  181. while(t!=x)
  182. {
  183. t=my_stack[top--];
  184. src_num[src_cnt]++;
  185. posi[t]=src_cnt;
  186. }
  187. }
  188. }
  189. void po_tarjan(int x,int fx)
  190. {
  191. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  192. for(int i=head[x];i;i=edge[i].nxt)
  193. {
  194. int to=edge[i].to;
  195. if(to==fx)continue;
  196. if(!dfn[to])
  197. {
  198. int pre=top;
  199. po_tarjan(to,x);
  200. low[x]=min(low[x],low[to]);
  201. if(dfn[x]<=low[to])
  202. {
  203. src_cnt++,posi[x]++;
  204. int t=0;
  205. while(top!=pre)
  206. {
  207. t=my_stack[top--];
  208. peo[src_cnt].push_back(t);
  209. }
  210. peo[src_cnt].push_back(x);
  211. sort(peo[src_cnt].begin(),peo[src_cnt].end());
  212. }
  213. }else low[x]=min(low[x],dfn[to]);
  214. }
  215. }
  216. void kruscal()
  217. {
  218. sort(e+1,e+m+1);
  219. int tot=0;ll ret=0;
  220. for(int i=1;i<=m;i++)
  221. {
  222. int f1=findf(e[i].l),f2=findf(e[i].r);
  223. if(f1==f2)continue;
  224. f[f1]=f2,tot++,ret+=e[i].v;
  225. if(tot==n-1)break;
  226. }
  227. if(tot==n-1)printf("%lld\n",ret);
  228. else printf("orz\n");
  229. }
  230. void min_dis_spfa(int st)
  231. {
  232. memset(dis,0x3f,sizeof(dis));
  233. dis[st]=0,used[st]=1;
  234. queue <int> M;
  235. M.push(st);
  236. while(!M.empty())
  237. {
  238. int u=M.front();
  239. M.pop();
  240. for(int i=head[u];i;i=edge[i].nxt)
  241. {
  242. int to=edge[i].to;
  243. if(dis[to]>dis[u]+edge[i].val)
  244. {
  245. dis[to]=dis[u]+edge[i].val;
  246. if(!used[to])used[to]=1,M.push(to);
  247. }
  248. }
  249. used[u]=0;
  250. }
  251. for(int i=1;i<=n;i++)
  252. {
  253. if(dis[i]==INF)printf("2147483647 ");
  254. else printf("%lld ",dis[i]);
  255. }
  256. }
  257. void diji(int st)
  258. {
  259. memset(dis,0x3f,sizeof(dis));
  260. dis[st]=0;
  261. priority_queue <node> M;
  262. M.push(node(st,0));
  263. while(!M.empty())
  264. {
  265. node temp=M.top();
  266. M.pop();
  267. int u=temp.p;
  268. if(used[u])continue;
  269. used[u]=1;
  270. for(int i=head[u];i;i=edge[i].nxt)
  271. {
  272. int to=edge[i].to;
  273. if(dis[to]>dis[u]+edge[i].val&&!used[to])dis[to]=dis[u]+edge[i].val,M.push(node(to,dis[to]));
  274. }
  275. }
  276. for(int i=1;i<=n;i++)printf("%lld ",dis[i]);
  277. }
  278. void max_dis_spfa(int st)
  279. {
  280. memset(dis,0,sizeof(dis));
  281. used[st]=1;
  282. dis[st]=src_num[st];
  283. queue <int> M;
  284. M.push(st);
  285. while(!M.empty())
  286. {
  287. int u=M.front();
  288. M.pop();
  289. for(int i=0;i<v[u].size();i++)
  290. {
  291. int to=v[u][i];
  292. if(dis[to]<dis[u]+src_num[to])
  293. {
  294. dis[to]=dis[u]+src_num[to];
  295. if(!used[to])used[to]=1,M.push(to);
  296. }
  297. }
  298. used[u]=0;
  299. }
  300. ll ans=0;
  301. for(int i=1;i<=nu;i++)ans=max(ans,dis[posi[spe[i]]]);
  302. printf("%lld\n",ans);
  303. }
  304. void build_MST()
  305. {
  306. kruscal();
  307. }
  308. void get_min_dis_road()
  309. {
  310. //min_dis_spfa(S);
  311. diji(S);
  312. }
  313. void solve_LCA()
  314. {
  315. tree_dfs(S,S),tree_redfs(S,S,S);
  316. for(int i=1;i<=m;i++)
  317. {
  318. int x,y;
  319. read(x),read(y);
  320. printf("%d\n",link_cut_LCA(x,y));
  321. }
  322. }
  323. void direc_tarjan()//有向图tarjan
  324. {
  325. for(int i=1;i<=n;i++)read(va[i]);
  326. read(S),read(nu);
  327. for(int i=1;i<=nu;i++)read(spe[i]);
  328. for(int i=1;i<=n;i++)if(!dfn[i])di_tarjan(i);
  329. for(int i=1;i<=n;i++)
  330. {
  331. for(int j=head[i];j;j=edge[j].nxt)
  332. {
  333. int to=edge[j].to;
  334. if(posi[i]==posi[to])continue;
  335. else v[posi[i]].push_back(posi[to]);
  336. }
  337. }
  338. max_dis_spfa(posi[S]);
  339. }
  340. void cut_line_tarjan()
  341. {
  342. for(int i=1;i<=n;i++)if(!dfn[i])ed_tarjan(i,-1);
  343. printf("%d ",count_cut_line);
  344. for(int i=1;i<=n;i++)
  345. {
  346. for(int j=head[i];j;j=edge[j].nxt)
  347. {
  348. int to=edge[j].to;
  349. if(posi[i]!=posi[to])inr[posi[to]]++;
  350. }
  351. }
  352. int s=0;
  353. for(int i=1;i<=src_cnt;i++)if(inr[i]==1)s++;
  354. printf("%d\n",(s+1)>>1);
  355. }
  356. void cut_point_tarjan()
  357. {
  358. for(int i=1;i<=n;i++)if(!dfn[i])po_tarjan(i,-1),posi[i]--;
  359. for(int i=1;i<=n;i++)if(posi[i]>=1)cut_point.push_back(i);
  360. printf("%d\n",cut_point.size());
  361. for(int i=0;i<cut_point.size();i++)printf("%d ",cut_point[i]);
  362. printf("\n");
  363. printf("%d\n",src_cnt);
  364. sort(peo+1,peo+src_cnt+1,cmp);
  365. for(int i=1;i<=src_cnt;i++,printf("\n"))for(int j=0;j<peo[i].size();j++)printf("%d ",peo[i][j]);
  366. }
  367. int ide(int x)
  368. {
  369. return x&1?x+1:x-1;
  370. }
  371. bool dinic_bfs()
  372. {
  373. memset(dis,0,sizeof(dis));
  374. memcpy(cur,head,sizeof(head));
  375. dis[S]=1;
  376. queue <int> M;
  377. M.push(S);
  378. while(!M.empty())
  379. {
  380. int u=M.front();
  381. M.pop();
  382. for(int i=head[u];i;i=edge[i].nxt)
  383. {
  384. int to=edge[i].to;
  385. if(edge[i].val&&!dis[to])dis[to]=dis[u]+1,M.push(to);
  386. }
  387. }
  388. return dis[T];
  389. }
  390. ll dinic_dfs(int x,ll lim)
  391. {
  392. if(x==T)return lim;
  393. ll ret=0;
  394. for(int i=cur[x];i;i=edge[i].nxt)
  395. {
  396. cur[x]=i;
  397. int to=edge[i].to;
  398. if(edge[i].val&&dis[to]==dis[x]+1)
  399. {
  400. ll temp=dinic_dfs(to,min(lim,edge[i].val));
  401. if(temp)
  402. {
  403. ret+=temp,lim-=temp;
  404. edge[i].val-=temp,edge[ide(i)].val+=temp;
  405. if(!lim)break;
  406. }
  407. }
  408. }
  409. return ret;
  410. }
  411. ll dinic()
  412. {
  413. ll ans=0;
  414. while(dinic_bfs())ans+=dinic_dfs(S,INF);
  415. return ans;
  416. }
  417. void max_flow()
  418. {
  419. printf("%lld\n",dinic());
  420. }
  421. int main()
  422. {
  423. read(n),read(m),read(S),read(T);
  424. init();
  425. for(int i=1;i<=m;i++)
  426. {
  427. int x,y;ll z;
  428. read(x),read(y),read(z);
  429. dadd(x,y,z);//,add(y,x,z);
  430. e[i].l=x,e[i].r=y,e[i].v=z;
  431. }
  432. max_flow();
  433. return 0;
  434. }

费用流:

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <stack>
  9. #include <vector>
  10. #define ll long long
  11. using namespace std;
  12. template <typename T>inline void read(T &x)
  13. {
  14. T f=1,c=0;char ch=getchar();
  15. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  16. while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
  17. x=c*f;
  18. }
  19. const int inf=0x3f3f3f3f;
  20. const ll INF=0x3f3f3f3f3f3f3f3fll;
  21. struct Edge
  22. {
  23. int nxt;
  24. int to;
  25. ll val;
  26. ll pri;
  27. }edge[5000005];
  28. struct E
  29. {
  30. int l,r;
  31. ll v;
  32. friend bool operator < (E a,E b)
  33. {
  34. return a.v<b.v;
  35. }
  36. }e[5000005];
  37. struct node
  38. {
  39. int p;ll v;
  40. node (){}
  41. node (int x,ll y):p(x),v(y){}
  42. friend bool operator < (node a,node b)
  43. {
  44. return a.v>b.v;
  45. }
  46. };
  47. int f[500005];
  48. int head[500005];
  49. ll dis[500005];
  50. ll va[500005];
  51. int dfn[500005],low[500005],posi[500005];
  52. ll src_num[500005],src_cnt;
  53. int my_stack[500005],top=0;
  54. int fa[500005][25];
  55. int dep[500005];
  56. int spe[500005],nu;
  57. int siz[500005],son[500005],ttop[500005];
  58. int inr[500005],our[500005];
  59. int cur[500005];
  60. int pre[500005];
  61. ll lim[500005];
  62. bool used[500005];
  63. int cnt=1,deep;
  64. int count_cut_line;
  65. int n,m,S,T;
  66. vector <int> v[500005];
  67. vector <int> peo[500005];
  68. vector <int> cut_point;
  69. bool cmp(vector <int> a,vector <int> b)
  70. {
  71. int lim=min(a.size(),b.size());
  72. for(int i=0;i<lim;i++)if(a[i]!=b[i])return a[i]<b[i];
  73. return a.size()<b.size();
  74. }
  75. void init()
  76. {
  77. for(int i=1;i<=n;i++)f[i]=i,head[i]=0;
  78. cnt=1;
  79. }
  80. void add(int l,int r,ll w)
  81. {
  82. edge[cnt].nxt=head[l];
  83. edge[cnt].to=r;
  84. edge[cnt].val=w;
  85. head[l]=cnt++;
  86. }
  87. void dadd(int l,int r,int w)
  88. {
  89. add(l,r,w),add(r,l,0);
  90. }
  91. void cost_add(int l,int r,ll w,ll p)
  92. {
  93. edge[cnt].nxt=head[l];
  94. edge[cnt].to=r;
  95. edge[cnt].val=w;
  96. edge[cnt].pri=p;
  97. head[l]=cnt++;
  98. }
  99. void cost_dadd(int l,int r,ll w,ll p)
  100. {
  101. cost_add(l,r,w,p),cost_add(r,l,0,-p);
  102. }
  103. int findf(int x)
  104. {
  105. return x==f[x]?x:f[x]=findf(f[x]);
  106. }
  107. void tree_dfs(int x,int fx)
  108. {
  109. dep[x]=dep[fx]+1,siz[x]=1,fa[x][0]=fx;
  110. for(int i=1;i<=20;i++)fa[x][i]=fa[fa[x][i-1]][i-1];
  111. for(int i=head[x];i;i=edge[i].nxt)
  112. {
  113. int to=edge[i].to;
  114. if(to==fx)continue;
  115. tree_dfs(to,x);
  116. siz[x]+=siz[to],son[x]=(siz[son[x]]>siz[to])?son[x]:to;
  117. }
  118. }
  119. void tree_redfs(int x,int topx,int fx)
  120. {
  121. ttop[x]=topx;
  122. if(son[x])tree_redfs(son[x],topx,x);
  123. for(int i=head[x];i;i=edge[i].nxt)
  124. {
  125. int to=edge[i].to;
  126. if(to==fx||to==son[x])continue;
  127. tree_redfs(to,to,x);
  128. }
  129. }
  130. int quick_jump_LCA(int x,int y)//倍增LCA
  131. {
  132. if(dep[x]>dep[y])swap(x,y);
  133. for(int i=20;i>=0;i--)if(dep[fa[y][i]]>=dep[x])y=fa[y][i];
  134. if(x==y)return x;
  135. int ret;
  136. for(int i=20;i>=0;i--)
  137. {
  138. if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
  139. else ret=fa[x][i];
  140. }
  141. return ret;
  142. }
  143. int link_cut_LCA(int x,int y)//树剖LCA
  144. {
  145. while(ttop[x]!=ttop[y])
  146. {
  147. if(dep[ttop[x]]<dep[ttop[y]])swap(x,y);
  148. x=fa[ttop[x]][0];
  149. }
  150. return dep[x]<dep[y]?x:y;
  151. }
  152. void di_tarjan(int x)
  153. {
  154. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  155. for(int i=head[x];i;i=edge[i].nxt)
  156. {
  157. int to=edge[i].to;
  158. if(!dfn[to])
  159. {
  160. di_tarjan(to);
  161. low[x]=min(low[x],low[to]);
  162. }else if(!posi[to])low[x]=min(low[x],dfn[to]);
  163. }
  164. if(dfn[x]==low[x])
  165. {
  166. src_cnt++;
  167. int t=0;
  168. while(t!=x)
  169. {
  170. t=my_stack[top--];
  171. src_num[src_cnt]+=va[t];
  172. posi[t]=src_cnt;
  173. }
  174. }
  175. }
  176. void ed_tarjan(int x,int fx)
  177. {
  178. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  179. for(int i=head[x];i;i=edge[i].nxt)
  180. {
  181. int to=edge[i].to;
  182. if(edge[i].val==fx)continue;
  183. if(!dfn[to])
  184. {
  185. ed_tarjan(to,edge[i].val);
  186. low[x]=min(low[x],low[to]);
  187. if(dfn[x]<low[to])count_cut_line++;
  188. }else if(!posi[to])low[x]=min(low[x],dfn[to]);
  189. }
  190. if(dfn[x]==low[x])
  191. {
  192. src_cnt++;
  193. int t=0;
  194. while(t!=x)
  195. {
  196. t=my_stack[top--];
  197. src_num[src_cnt]++;
  198. posi[t]=src_cnt;
  199. }
  200. }
  201. }
  202. void po_tarjan(int x,int fx)
  203. {
  204. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  205. for(int i=head[x];i;i=edge[i].nxt)
  206. {
  207. int to=edge[i].to;
  208. if(to==fx)continue;
  209. if(!dfn[to])
  210. {
  211. int pre=top;
  212. po_tarjan(to,x);
  213. low[x]=min(low[x],low[to]);
  214. if(dfn[x]<=low[to])
  215. {
  216. src_cnt++,posi[x]++;
  217. int t=0;
  218. while(top!=pre)
  219. {
  220. t=my_stack[top--];
  221. peo[src_cnt].push_back(t);
  222. }
  223. peo[src_cnt].push_back(x);
  224. sort(peo[src_cnt].begin(),peo[src_cnt].end());
  225. }
  226. }else low[x]=min(low[x],dfn[to]);
  227. }
  228. }
  229. void kruscal()
  230. {
  231. sort(e+1,e+m+1);
  232. int tot=0;ll ret=0;
  233. for(int i=1;i<=m;i++)
  234. {
  235. int f1=findf(e[i].l),f2=findf(e[i].r);
  236. if(f1==f2)continue;
  237. f[f1]=f2,tot++,ret+=e[i].v;
  238. if(tot==n-1)break;
  239. }
  240. if(tot==n-1)printf("%lld\n",ret);
  241. else printf("orz\n");
  242. }
  243. void min_dis_spfa(int st)
  244. {
  245. memset(dis,0x3f,sizeof(dis));
  246. dis[st]=0,used[st]=1;
  247. queue <int> M;
  248. M.push(st);
  249. while(!M.empty())
  250. {
  251. int u=M.front();
  252. M.pop();
  253. for(int i=head[u];i;i=edge[i].nxt)
  254. {
  255. int to=edge[i].to;
  256. if(dis[to]>dis[u]+edge[i].val)
  257. {
  258. dis[to]=dis[u]+edge[i].val;
  259. if(!used[to])used[to]=1,M.push(to);
  260. }
  261. }
  262. used[u]=0;
  263. }
  264. for(int i=1;i<=n;i++)
  265. {
  266. if(dis[i]==INF)printf("2147483647 ");
  267. else printf("%lld ",dis[i]);
  268. }
  269. }
  270. void diji(int st)
  271. {
  272. memset(dis,0x3f,sizeof(dis));
  273. dis[st]=0;
  274. priority_queue <node> M;
  275. M.push(node(st,0));
  276. while(!M.empty())
  277. {
  278. node temp=M.top();
  279. M.pop();
  280. int u=temp.p;
  281. if(used[u])continue;
  282. used[u]=1;
  283. for(int i=head[u];i;i=edge[i].nxt)
  284. {
  285. int to=edge[i].to;
  286. if(dis[to]>dis[u]+edge[i].val&&!used[to])dis[to]=dis[u]+edge[i].val,M.push(node(to,dis[to]));
  287. }
  288. }
  289. for(int i=1;i<=n;i++)printf("%lld ",dis[i]);
  290. }
  291. void max_dis_spfa(int st)
  292. {
  293. memset(dis,0,sizeof(dis));
  294. used[st]=1;
  295. dis[st]=src_num[st];
  296. queue <int> M;
  297. M.push(st);
  298. while(!M.empty())
  299. {
  300. int u=M.front();
  301. M.pop();
  302. for(int i=0;i<v[u].size();i++)
  303. {
  304. int to=v[u][i];
  305. if(dis[to]<dis[u]+src_num[to])
  306. {
  307. dis[to]=dis[u]+src_num[to];
  308. if(!used[to])used[to]=1,M.push(to);
  309. }
  310. }
  311. used[u]=0;
  312. }
  313. ll ans=0;
  314. for(int i=1;i<=nu;i++)ans=max(ans,dis[posi[spe[i]]]);
  315. printf("%lld\n",ans);
  316. }
  317. void build_MST()
  318. {
  319. kruscal();
  320. }
  321. void get_min_dis_road()
  322. {
  323. //min_dis_spfa(S);
  324. diji(S);
  325. }
  326. void solve_LCA()
  327. {
  328. tree_dfs(S,S),tree_redfs(S,S,S);
  329. for(int i=1;i<=m;i++)
  330. {
  331. int x,y;
  332. read(x),read(y);
  333. printf("%d\n",link_cut_LCA(x,y));
  334. }
  335. }
  336. void direc_tarjan()//有向图tarjan
  337. {
  338. for(int i=1;i<=n;i++)read(va[i]);
  339. read(S),read(nu);
  340. for(int i=1;i<=nu;i++)read(spe[i]);
  341. for(int i=1;i<=n;i++)if(!dfn[i])di_tarjan(i);
  342. for(int i=1;i<=n;i++)
  343. {
  344. for(int j=head[i];j;j=edge[j].nxt)
  345. {
  346. int to=edge[j].to;
  347. if(posi[i]==posi[to])continue;
  348. else v[posi[i]].push_back(posi[to]);
  349. }
  350. }
  351. max_dis_spfa(posi[S]);
  352. }
  353. void cut_line_tarjan()
  354. {
  355. for(int i=1;i<=n;i++)if(!dfn[i])ed_tarjan(i,-1);
  356. printf("%d ",count_cut_line);
  357. for(int i=1;i<=n;i++)
  358. {
  359. for(int j=head[i];j;j=edge[j].nxt)
  360. {
  361. int to=edge[j].to;
  362. if(posi[i]!=posi[to])inr[posi[to]]++;
  363. }
  364. }
  365. int s=0;
  366. for(int i=1;i<=src_cnt;i++)if(inr[i]==1)s++;
  367. printf("%d\n",(s+1)>>1);
  368. }
  369. void cut_point_tarjan()
  370. {
  371. for(int i=1;i<=n;i++)if(!dfn[i])po_tarjan(i,-1),posi[i]--;
  372. for(int i=1;i<=n;i++)if(posi[i]>=1)cut_point.push_back(i);
  373. printf("%d\n",cut_point.size());
  374. for(int i=0;i<cut_point.size();i++)printf("%d ",cut_point[i]);
  375. printf("\n");
  376. printf("%d\n",src_cnt);
  377. sort(peo+1,peo+src_cnt+1,cmp);
  378. for(int i=1;i<=src_cnt;i++,printf("\n"))for(int j=0;j<peo[i].size();j++)printf("%d ",peo[i][j]);
  379. }
  380. int ide(int x)
  381. {
  382. return x&1?x+1:x-1;
  383. }
  384. bool dinic_bfs()
  385. {
  386. memset(dis,0,sizeof(dis));
  387. memcpy(cur,head,sizeof(head));
  388. dis[S]=1;
  389. queue <int> M;
  390. M.push(S);
  391. while(!M.empty())
  392. {
  393. int u=M.front();
  394. M.pop();
  395. for(int i=head[u];i;i=edge[i].nxt)
  396. {
  397. int to=edge[i].to;
  398. if(edge[i].val&&!dis[to])dis[to]=dis[u]+1,M.push(to);
  399. }
  400. }
  401. return dis[T];
  402. }
  403. ll dinic_dfs(int x,ll lim)
  404. {
  405. if(x==T)return lim;
  406. ll ret=0;
  407. for(int i=cur[x];i;i=edge[i].nxt)
  408. {
  409. cur[x]=i;
  410. int to=edge[i].to;
  411. if(edge[i].val&&dis[to]==dis[x]+1)
  412. {
  413. ll temp=dinic_dfs(to,min(lim,edge[i].val));
  414. if(temp)
  415. {
  416. ret+=temp,lim-=temp;
  417. edge[i].val-=temp,edge[ide(i)].val+=temp;
  418. if(!lim)break;
  419. }
  420. }
  421. }
  422. return ret;
  423. }
  424. ll dinic()
  425. {
  426. ll ans=0;
  427. while(dinic_bfs())ans+=dinic_dfs(S,INF);
  428. return ans;
  429. }
  430. void max_flow()
  431. {
  432. printf("%lld\n",dinic());
  433. }
  434. bool EK_spfa()
  435. {
  436. memset(pre,-1,sizeof(pre));
  437. memset(f,0,sizeof(f));
  438. memset(dis,0x3f,sizeof(dis));
  439. dis[S]=0,lim[S]=INF,used[S]=1;
  440. queue <int> M;
  441. M.push(S);
  442. while(!M.empty())
  443. {
  444. int u=M.front();
  445. M.pop();
  446. for(int i=head[u];i;i=edge[i].nxt)
  447. {
  448. int to=edge[i].to;
  449. if(edge[i].val&&dis[to]>dis[u]+edge[i].pri)
  450. {
  451. dis[to]=dis[u]+edge[i].pri;
  452. pre[to]=i,f[to]=u,lim[to]=min(lim[u],edge[i].val);
  453. if(!used[to])used[to]=1,M.push(to);
  454. }
  455. }
  456. used[u]=0;
  457. }
  458. return pre[T]!=-1;
  459. }
  460. void EK()
  461. {
  462. ll maxf=0,minv=0;
  463. while(EK_spfa())
  464. {
  465. maxf+=lim[T],minv+=dis[T]*lim[T];
  466. int temp=T;
  467. while(temp!=S)edge[pre[temp]].val-=lim[T],edge[ide(pre[temp])].val+=lim[T],temp=f[temp];
  468. }
  469. printf("%lld %lld\n",maxf,minv);
  470. }
  471. void min_cost_max_flow()
  472. {
  473. S=1,T=n;
  474. for(int i=1;i<=m;i++)
  475. {
  476. int x,y;ll z,w;
  477. read(x),read(y),read(z),read(w);
  478. cost_dadd(x,y,z,w);
  479. }
  480. EK();
  481. }
  482. int main()
  483. {
  484. read(n),read(m);//,read(S),read(T);
  485. init();
  486. min_cost_max_flow();
  487. return 0;
  488. for(int i=1;i<=m;i++)
  489. {
  490. int x,y;ll z;
  491. read(x),read(y),read(z);
  492. dadd(x,y,z);//,add(y,x,z);
  493. e[i].l=x,e[i].r=y,e[i].v=z;
  494. }
  495. max_flow();
  496. return 0;
  497. }

有源汇上下界最大流

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <stack>
  9. #include <vector>
  10. #define ll long long
  11. using namespace std;
  12. const int maxn=2000005;
  13. const int maxm=5000005;
  14. template <typename T>inline void read(T &x)
  15. {
  16. T f=1,c=0;char ch=getchar();
  17. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  18. while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
  19. x=c*f;
  20. }
  21. const int inf=0x3f3f3f3f;
  22. const ll INF=0x3f3f3f3f3f3f3f3fll;
  23. struct Edge
  24. {
  25. int nxt;
  26. int to;
  27. ll val;
  28. ll pri;
  29. }edge[maxm];
  30. struct E
  31. {
  32. int l,r;
  33. ll v;
  34. friend bool operator < (E a,E b)
  35. {
  36. return a.v<b.v;
  37. }
  38. }e[maxm];
  39. struct node
  40. {
  41. int p;ll v;
  42. node (){}
  43. node (int x,ll y):p(x),v(y){}
  44. friend bool operator < (node a,node b)
  45. {
  46. return a.v>b.v;
  47. }
  48. };
  49. int f[maxn];
  50. int head[maxn];
  51. ll dis[maxn];
  52. ll va[maxn];
  53. int dfn[maxn],low[maxn],posi[maxn];
  54. ll src_num[maxn],src_cnt;
  55. int my_stack[maxn],top=0;
  56. int fa[maxn][25];
  57. int dep[maxn];
  58. int spe[maxn],nu;
  59. int siz[maxn],son[maxn],ttop[maxn];
  60. int inr[maxn],our[maxn];
  61. int cur[maxn];
  62. int pre[maxn];
  63. ll lim[maxn];
  64. bool used[maxn];
  65. ll fin[maxn],fout[maxn];
  66. int cnt=1,deep;
  67. int count_cut_line;
  68. int n,m,S,T;
  69. vector <int> v[maxn];
  70. vector <int> peo[maxn];
  71. vector <int> cut_point;
  72. bool cmp(vector <int> a,vector <int> b)
  73. {
  74. int lim=min(a.size(),b.size());
  75. for(int i=0;i<lim;i++)if(a[i]!=b[i])return a[i]<b[i];
  76. return a.size()<b.size();
  77. }
  78. void init()
  79. {
  80. //for(int i=1;i<=n;i++)f[i]=i,head[i]=0;
  81. cnt=1;
  82. }
  83. void add(int l,int r,ll w)
  84. {
  85. edge[cnt].nxt=head[l];
  86. edge[cnt].to=r;
  87. edge[cnt].val=w;
  88. head[l]=cnt++;
  89. }
  90. void dadd(int l,int r,ll w)
  91. {
  92. add(l,r,w),add(r,l,0);
  93. }
  94. void cost_add(int l,int r,ll w,ll p)
  95. {
  96. edge[cnt].nxt=head[l];
  97. edge[cnt].to=r;
  98. edge[cnt].val=w;
  99. edge[cnt].pri=p;
  100. head[l]=cnt++;
  101. }
  102. void cost_dadd(int l,int r,ll w,ll p)
  103. {
  104. cost_add(l,r,w,p),cost_add(r,l,0,-p);
  105. }
  106. int findf(int x)
  107. {
  108. return x==f[x]?x:f[x]=findf(f[x]);
  109. }
  110. void tree_dfs(int x,int fx)
  111. {
  112. dep[x]=dep[fx]+1,siz[x]=1,fa[x][0]=fx;
  113. for(int i=1;i<=20;i++)fa[x][i]=fa[fa[x][i-1]][i-1];
  114. for(int i=head[x];i;i=edge[i].nxt)
  115. {
  116. int to=edge[i].to;
  117. if(to==fx)continue;
  118. tree_dfs(to,x);
  119. siz[x]+=siz[to],son[x]=(siz[son[x]]>siz[to])?son[x]:to;
  120. }
  121. }
  122. void tree_redfs(int x,int topx,int fx)
  123. {
  124. ttop[x]=topx;
  125. if(son[x])tree_redfs(son[x],topx,x);
  126. for(int i=head[x];i;i=edge[i].nxt)
  127. {
  128. int to=edge[i].to;
  129. if(to==fx||to==son[x])continue;
  130. tree_redfs(to,to,x);
  131. }
  132. }
  133. int quick_jump_LCA(int x,int y)//倍增LCA
  134. {
  135. if(dep[x]>dep[y])swap(x,y);
  136. for(int i=20;i>=0;i--)if(dep[fa[y][i]]>=dep[x])y=fa[y][i];
  137. if(x==y)return x;
  138. int ret;
  139. for(int i=20;i>=0;i--)
  140. {
  141. if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
  142. else ret=fa[x][i];
  143. }
  144. return ret;
  145. }
  146. int link_cut_LCA(int x,int y)//树剖LCA
  147. {
  148. while(ttop[x]!=ttop[y])
  149. {
  150. if(dep[ttop[x]]<dep[ttop[y]])swap(x,y);
  151. x=fa[ttop[x]][0];
  152. }
  153. return dep[x]<dep[y]?x:y;
  154. }
  155. void di_tarjan(int x)
  156. {
  157. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  158. for(int i=head[x];i;i=edge[i].nxt)
  159. {
  160. int to=edge[i].to;
  161. if(!dfn[to])
  162. {
  163. di_tarjan(to);
  164. low[x]=min(low[x],low[to]);
  165. }else if(!posi[to])low[x]=min(low[x],dfn[to]);
  166. }
  167. if(dfn[x]==low[x])
  168. {
  169. src_cnt++;
  170. int t=0;
  171. while(t!=x)
  172. {
  173. t=my_stack[top--];
  174. src_num[src_cnt]++;
  175. posi[t]=src_cnt;
  176. }
  177. }
  178. }
  179. void ed_tarjan(int x,int fx)
  180. {
  181. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  182. for(int i=head[x];i;i=edge[i].nxt)
  183. {
  184. int to=edge[i].to;
  185. if(edge[i].val==fx)continue;
  186. if(!dfn[to])
  187. {
  188. ed_tarjan(to,edge[i].val);
  189. low[x]=min(low[x],low[to]);
  190. if(dfn[x]<low[to])count_cut_line++;
  191. }else if(!posi[to])low[x]=min(low[x],dfn[to]);
  192. }
  193. if(dfn[x]==low[x])
  194. {
  195. src_cnt++;
  196. int t=0;
  197. while(t!=x)
  198. {
  199. t=my_stack[top--];
  200. src_num[src_cnt]++;
  201. posi[t]=src_cnt;
  202. }
  203. }
  204. }
  205. void po_tarjan(int x,int fx)
  206. {
  207. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  208. for(int i=head[x];i;i=edge[i].nxt)
  209. {
  210. int to=edge[i].to;
  211. if(to==fx)continue;
  212. if(!dfn[to])
  213. {
  214. int pre=top;
  215. po_tarjan(to,x);
  216. low[x]=min(low[x],low[to]);
  217. if(dfn[x]<=low[to])
  218. {
  219. src_cnt++,posi[x]++;
  220. int t=0;
  221. while(top!=pre)
  222. {
  223. t=my_stack[top--];
  224. peo[src_cnt].push_back(t);
  225. }
  226. peo[src_cnt].push_back(x);
  227. sort(peo[src_cnt].begin(),peo[src_cnt].end());
  228. }
  229. }else low[x]=min(low[x],dfn[to]);
  230. }
  231. }
  232. void kruscal()
  233. {
  234. sort(e+1,e+m+1);
  235. int tot=0;ll ret=0;
  236. for(int i=1;i<=m;i++)
  237. {
  238. int f1=findf(e[i].l),f2=findf(e[i].r);
  239. if(f1==f2)continue;
  240. f[f1]=f2,tot++,ret+=e[i].v;
  241. if(tot==n-1)break;
  242. }
  243. if(tot==n-1)printf("%lld\n",ret);
  244. else printf("orz\n");
  245. }
  246. void min_dis_spfa(int st)
  247. {
  248. memset(dis,0x3f,sizeof(dis));
  249. dis[st]=0,used[st]=1;
  250. queue <int> M;
  251. M.push(st);
  252. while(!M.empty())
  253. {
  254. int u=M.front();
  255. M.pop();
  256. for(int i=head[u];i;i=edge[i].nxt)
  257. {
  258. int to=edge[i].to;
  259. if(dis[to]>dis[u]+edge[i].val)
  260. {
  261. dis[to]=dis[u]+edge[i].val;
  262. if(!used[to])used[to]=1,M.push(to);
  263. }
  264. }
  265. used[u]=0;
  266. }
  267. for(int i=1;i<=n;i++)
  268. {
  269. if(dis[i]==INF)printf("2147483647 ");
  270. else printf("%lld ",dis[i]);
  271. }
  272. }
  273. void diji(int st)
  274. {
  275. memset(dis,0x3f,sizeof(dis));
  276. dis[st]=0;
  277. priority_queue <node> M;
  278. M.push(node(st,0));
  279. while(!M.empty())
  280. {
  281. node temp=M.top();
  282. M.pop();
  283. int u=temp.p;
  284. if(used[u])continue;
  285. used[u]=1;
  286. for(int i=head[u];i;i=edge[i].nxt)
  287. {
  288. int to=edge[i].to;
  289. if(dis[to]>dis[u]+edge[i].val&&!used[to])dis[to]=dis[u]+edge[i].val,M.push(node(to,dis[to]));
  290. }
  291. }
  292. for(int i=1;i<=n;i++)printf("%lld ",dis[i]);
  293. }
  294. void max_dis_spfa(int st)
  295. {
  296. memset(dis,0,sizeof(dis));
  297. used[st]=1;
  298. dis[st]=src_num[st];
  299. queue <int> M;
  300. M.push(st);
  301. while(!M.empty())
  302. {
  303. int u=M.front();
  304. M.pop();
  305. for(int i=0;i<v[u].size();i++)
  306. {
  307. int to=v[u][i];
  308. if(dis[to]<dis[u]+src_num[to])
  309. {
  310. dis[to]=dis[u]+src_num[to];
  311. if(!used[to])used[to]=1,M.push(to);
  312. }
  313. }
  314. used[u]=0;
  315. }
  316. ll ans=0;
  317. for(int i=1;i<=nu;i++)ans=max(ans,dis[posi[spe[i]]]);
  318. printf("%lld\n",ans);
  319. }
  320. void build_MST()
  321. {
  322. kruscal();
  323. }
  324. void get_min_dis_road()
  325. {
  326. //min_dis_spfa(S);
  327. diji(S);
  328. }
  329. void solve_LCA()
  330. {
  331. tree_dfs(S,S),tree_redfs(S,S,S);
  332. for(int i=1;i<=m;i++)
  333. {
  334. int x,y;
  335. read(x),read(y);
  336. printf("%d\n",link_cut_LCA(x,y));
  337. }
  338. }
  339. void direc_tarjan()//有向图tarjan
  340. {
  341. for(int i=1;i<=n;i++)read(va[i]);
  342. read(S),read(nu);
  343. for(int i=1;i<=nu;i++)read(spe[i]);
  344. for(int i=1;i<=n;i++)if(!dfn[i])di_tarjan(i);
  345. for(int i=1;i<=n;i++)
  346. {
  347. for(int j=head[i];j;j=edge[j].nxt)
  348. {
  349. int to=edge[j].to;
  350. if(posi[i]==posi[to])continue;
  351. else v[posi[i]].push_back(posi[to]);
  352. }
  353. }
  354. max_dis_spfa(posi[S]);
  355. }
  356. void cut_line_tarjan()
  357. {
  358. for(int i=1;i<=n;i++)if(!dfn[i])ed_tarjan(i,-1);
  359. printf("%d ",count_cut_line);
  360. for(int i=1;i<=n;i++)
  361. {
  362. for(int j=head[i];j;j=edge[j].nxt)
  363. {
  364. int to=edge[j].to;
  365. if(posi[i]!=posi[to])inr[posi[to]]++;
  366. }
  367. }
  368. int s=0;
  369. for(int i=1;i<=src_cnt;i++)if(inr[i]==1)s++;
  370. printf("%d\n",(s+1)>>1);
  371. }
  372. void cut_point_tarjan()
  373. {
  374. for(int i=1;i<=n;i++)if(!dfn[i])po_tarjan(i,-1),posi[i]--;
  375. for(int i=1;i<=n;i++)if(posi[i]>=1)cut_point.push_back(i);
  376. printf("%d\n",cut_point.size());
  377. for(int i=0;i<cut_point.size();i++)printf("%d ",cut_point[i]);
  378. printf("\n");
  379. printf("%d\n",src_cnt);
  380. sort(peo+1,peo+src_cnt+1,cmp);
  381. for(int i=1;i<=src_cnt;i++,printf("\n"))for(int j=0;j<peo[i].size();j++)printf("%d ",peo[i][j]);
  382. }
  383. int ide(int x)
  384. {
  385. return x&1?x+1:x-1;
  386. }
  387. bool dinic_bfs()
  388. {
  389. memset(dis,0,sizeof(dis));
  390. memcpy(cur,head,sizeof(head));
  391. dis[S]=1;
  392. queue <int> M;
  393. M.push(S);
  394. while(!M.empty())
  395. {
  396. int u=M.front();
  397. M.pop();
  398. for(int i=head[u];i;i=edge[i].nxt)
  399. {
  400. int to=edge[i].to;
  401. if(edge[i].val&&!dis[to])dis[to]=dis[u]+1,M.push(to);
  402. }
  403. }
  404. return dis[T];
  405. }
  406. ll dinic_dfs(int x,ll lim)
  407. {
  408. if(x==T)return lim;
  409. ll ret=0;
  410. for(int i=cur[x];i;i=edge[i].nxt)
  411. {
  412. cur[x]=i;
  413. int to=edge[i].to;
  414. if(edge[i].val&&dis[to]==dis[x]+1)
  415. {
  416. ll temp=dinic_dfs(to,min(lim,edge[i].val));
  417. if(temp)
  418. {
  419. ret+=temp,lim-=temp;
  420. edge[i].val-=temp,edge[ide(i)].val+=temp;
  421. if(!lim)break;
  422. }
  423. }
  424. }
  425. return ret;
  426. }
  427. ll dinic()
  428. {
  429. ll ans=0;
  430. while(dinic_bfs())ans+=dinic_dfs(S,INF);
  431. return ans;
  432. }
  433. void max_flow()
  434. {
  435. printf("%lld\n",dinic());
  436. }
  437. bool EK_spfa()
  438. {
  439. memset(pre,-1,sizeof(pre));
  440. memset(f,0,sizeof(f));
  441. memset(dis,0x3f,sizeof(dis));
  442. dis[S]=0,lim[S]=INF,used[S]=1;
  443. queue <int> M;
  444. M.push(S);
  445. while(!M.empty())
  446. {
  447. int u=M.front();
  448. M.pop();
  449. for(int i=head[u];i;i=edge[i].nxt)
  450. {
  451. int to=edge[i].to;
  452. if(edge[i].val&&dis[to]>dis[u]+edge[i].pri)
  453. {
  454. dis[to]=dis[u]+edge[i].pri;
  455. pre[to]=i,f[to]=u,lim[to]=min(lim[u],edge[i].val);
  456. if(!used[to])used[to]=1,M.push(to);
  457. }
  458. }
  459. used[u]=0;
  460. }
  461. return pre[T]!=-1;
  462. }
  463. void EK()
  464. {
  465. ll maxf=0,minv=0;
  466. while(EK_spfa())
  467. {
  468. maxf+=lim[T],minv+=dis[T]*lim[T];
  469. int temp=T;
  470. while(temp!=S)edge[pre[temp]].val-=lim[T],edge[ide(pre[temp])].val+=lim[T],temp=f[temp];
  471. }
  472. printf("%lld %lld\n",maxf,minv);
  473. }
  474. void min_cost_max_flow()
  475. {
  476. S=1,T=n;
  477. for(int i=1;i<=m;i++)
  478. {
  479. int x,y;ll z,w;
  480. read(x),read(y),read(z),read(w);
  481. cost_dadd(x,y,z,w);
  482. }
  483. EK();
  484. }
  485. void two_SAT()
  486. {
  487. for(int i=1;i<=m;i++)
  488. {
  489. int x,y,z,w;
  490. read(x),read(y),read(z),read(w);
  491. if(y==1&&w==1)add(x+n,z,0),add(z+n,x,0);
  492. else if(y==1)add(x+n,z+n,0),add(z,x,0);
  493. else if(w==1)add(x,z,0),add(z+n,x+n,0);
  494. else add(x,z+n,0),add(z,x+n,0);
  495. }
  496. n<<=1;
  497. for(int i=1;i<=n;i++)if(!dfn[i])di_tarjan(i);
  498. n>>=1;
  499. for(int i=1;i<=n;i++)if(posi[i]==posi[i+n]){printf("IMPOSSIBLE\n");exit(0);}
  500. printf("POSSIBLE\n");
  501. for(int i=1;i<=n;i++)
  502. {
  503. if(posi[i]<posi[i+n])printf("1 ");
  504. else printf("0 ");
  505. }
  506. printf("\n");
  507. }
  508. bool dfs(int x)
  509. {
  510. for(int i=head[x];i;i=edge[i].nxt)
  511. {
  512. int to=edge[i].to;
  513. if(used[to])continue;
  514. used[to]=1;
  515. if(!f[to]||dfs(f[to])){f[to]=x;return 1;}
  516. }
  517. return 0;
  518. }
  519. int hungary()
  520. {
  521. int ret=0;
  522. for(int i=1;i<=n;i++)
  523. {
  524. for(int j=1;j<=n+m;j++)used[j]=0;
  525. if(dfs(i))ret++;
  526. }
  527. return ret;
  528. }
  529. void two_match()
  530. {
  531. read(n),read(m),read(S);
  532. for(int i=1;i<=S;i++)
  533. {
  534. int x,y;
  535. read(x),read(y);
  536. if(x>n||y>m)continue;
  537. add(x,y+n,0),add(y+n,x,0);
  538. }
  539. printf("%d\n",hungary());
  540. }
  541. void upper_lower_maxflow()
  542. {
  543. int temps=S,tempt=T;
  544. S=n+1,T=n+2;
  545. ll sum=0;
  546. for(int i=1;i<=n;i++)
  547. {
  548. if(fin[i]>fout[i])dadd(S,i,fin[i]-fout[i]),sum+=fin[i]-fout[i];
  549. else dadd(i,T,fout[i]-fin[i]);
  550. }
  551. if(dinic()<sum)printf("please go home to sleep\n");
  552. else S=temps,T=tempt,printf("%lld\n",dinic());
  553. }
  554. void upper_lower_minflow()
  555. {
  556. int temps=S,tempt=T;
  557. S=n+1,T=n+2;
  558. ll sum=0;
  559. for(int i=1;i<=n;i++)
  560. {
  561. if(fin[i]>fout[i])dadd(S,i,fin[i]-fout[i]),sum+=fin[i]-fout[i];
  562. else dadd(i,T,fout[i]-fin[i]);
  563. }
  564. if(dinic()<sum)printf("please go home to sleep\n");
  565. else S=tempt,T=temps,printf("%lld\n",INF-dinic());
  566. }
  567. int main()
  568. {
  569. read(n),read(m),read(S),read(T);
  570. init();
  571. for(int i=1;i<=m;i++)
  572. {
  573. int x,y;ll z,w;
  574. read(x),read(y),read(z),read(w);
  575. fin[y]+=z,fout[x]+=z;
  576. dadd(x,y,w-z);
  577. e[i].l=x,e[i].r=y,e[i].v=z;
  578. }
  579. dadd(T,S,INF);
  580. upper_lower_maxflow();
  581. return 0;
  582. }

有源汇上下界最小流

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <stack>
  9. #include <vector>
  10. #define ll long long
  11. using namespace std;
  12. const int maxn=2000005;
  13. const int maxm=5000005;
  14. template <typename T>inline void read(T &x)
  15. {
  16. T f=1,c=0;char ch=getchar();
  17. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  18. while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
  19. x=c*f;
  20. }
  21. const int inf=0x3f3f3f3f;
  22. const ll INF=0x3f3f3f3f3f3f3f3fll;
  23. struct Edge
  24. {
  25. int nxt;
  26. int to;
  27. ll val;
  28. ll pri;
  29. }edge[maxm];
  30. struct E
  31. {
  32. int l,r;
  33. ll v;
  34. friend bool operator < (E a,E b)
  35. {
  36. return a.v<b.v;
  37. }
  38. }e[maxm];
  39. struct node
  40. {
  41. int p;ll v;
  42. node (){}
  43. node (int x,ll y):p(x),v(y){}
  44. friend bool operator < (node a,node b)
  45. {
  46. return a.v>b.v;
  47. }
  48. };
  49. int f[maxn];
  50. int head[maxn];
  51. ll dis[maxn];
  52. ll va[maxn];
  53. int dfn[maxn],low[maxn],posi[maxn];
  54. ll src_num[maxn],src_cnt;
  55. int my_stack[maxn],top=0;
  56. int fa[maxn][25];
  57. int dep[maxn];
  58. int spe[maxn],nu;
  59. int siz[maxn],son[maxn],ttop[maxn];
  60. int inr[maxn],our[maxn];
  61. int cur[maxn];
  62. int pre[maxn];
  63. ll lim[maxn];
  64. bool used[maxn];
  65. ll fin[maxn],fout[maxn];
  66. int cnt=1,deep;
  67. int count_cut_line;
  68. int n,m,S,T;
  69. vector <int> v[maxn];
  70. vector <int> peo[maxn];
  71. vector <int> cut_point;
  72. bool cmp(vector <int> a,vector <int> b)
  73. {
  74. int lim=min(a.size(),b.size());
  75. for(int i=0;i<lim;i++)if(a[i]!=b[i])return a[i]<b[i];
  76. return a.size()<b.size();
  77. }
  78. void init()
  79. {
  80. //for(int i=1;i<=n;i++)f[i]=i,head[i]=0;
  81. cnt=1;
  82. }
  83. void add(int l,int r,ll w)
  84. {
  85. edge[cnt].nxt=head[l];
  86. edge[cnt].to=r;
  87. edge[cnt].val=w;
  88. head[l]=cnt++;
  89. }
  90. void dadd(int l,int r,ll w)
  91. {
  92. add(l,r,w),add(r,l,0);
  93. }
  94. void cost_add(int l,int r,ll w,ll p)
  95. {
  96. edge[cnt].nxt=head[l];
  97. edge[cnt].to=r;
  98. edge[cnt].val=w;
  99. edge[cnt].pri=p;
  100. head[l]=cnt++;
  101. }
  102. void cost_dadd(int l,int r,ll w,ll p)
  103. {
  104. cost_add(l,r,w,p),cost_add(r,l,0,-p);
  105. }
  106. int findf(int x)
  107. {
  108. return x==f[x]?x:f[x]=findf(f[x]);
  109. }
  110. void tree_dfs(int x,int fx)
  111. {
  112. dep[x]=dep[fx]+1,siz[x]=1,fa[x][0]=fx;
  113. for(int i=1;i<=20;i++)fa[x][i]=fa[fa[x][i-1]][i-1];
  114. for(int i=head[x];i;i=edge[i].nxt)
  115. {
  116. int to=edge[i].to;
  117. if(to==fx)continue;
  118. tree_dfs(to,x);
  119. siz[x]+=siz[to],son[x]=(siz[son[x]]>siz[to])?son[x]:to;
  120. }
  121. }
  122. void tree_redfs(int x,int topx,int fx)
  123. {
  124. ttop[x]=topx;
  125. if(son[x])tree_redfs(son[x],topx,x);
  126. for(int i=head[x];i;i=edge[i].nxt)
  127. {
  128. int to=edge[i].to;
  129. if(to==fx||to==son[x])continue;
  130. tree_redfs(to,to,x);
  131. }
  132. }
  133. int quick_jump_LCA(int x,int y)//倍增LCA
  134. {
  135. if(dep[x]>dep[y])swap(x,y);
  136. for(int i=20;i>=0;i--)if(dep[fa[y][i]]>=dep[x])y=fa[y][i];
  137. if(x==y)return x;
  138. int ret;
  139. for(int i=20;i>=0;i--)
  140. {
  141. if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
  142. else ret=fa[x][i];
  143. }
  144. return ret;
  145. }
  146. int link_cut_LCA(int x,int y)//树剖LCA
  147. {
  148. while(ttop[x]!=ttop[y])
  149. {
  150. if(dep[ttop[x]]<dep[ttop[y]])swap(x,y);
  151. x=fa[ttop[x]][0];
  152. }
  153. return dep[x]<dep[y]?x:y;
  154. }
  155. void di_tarjan(int x)
  156. {
  157. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  158. for(int i=head[x];i;i=edge[i].nxt)
  159. {
  160. int to=edge[i].to;
  161. if(!dfn[to])
  162. {
  163. di_tarjan(to);
  164. low[x]=min(low[x],low[to]);
  165. }else if(!posi[to])low[x]=min(low[x],dfn[to]);
  166. }
  167. if(dfn[x]==low[x])
  168. {
  169. src_cnt++;
  170. int t=0;
  171. while(t!=x)
  172. {
  173. t=my_stack[top--];
  174. src_num[src_cnt]++;
  175. posi[t]=src_cnt;
  176. }
  177. }
  178. }
  179. void ed_tarjan(int x,int fx)
  180. {
  181. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  182. for(int i=head[x];i;i=edge[i].nxt)
  183. {
  184. int to=edge[i].to;
  185. if(edge[i].val==fx)continue;
  186. if(!dfn[to])
  187. {
  188. ed_tarjan(to,edge[i].val);
  189. low[x]=min(low[x],low[to]);
  190. if(dfn[x]<low[to])count_cut_line++;
  191. }else if(!posi[to])low[x]=min(low[x],dfn[to]);
  192. }
  193. if(dfn[x]==low[x])
  194. {
  195. src_cnt++;
  196. int t=0;
  197. while(t!=x)
  198. {
  199. t=my_stack[top--];
  200. src_num[src_cnt]++;
  201. posi[t]=src_cnt;
  202. }
  203. }
  204. }
  205. void po_tarjan(int x,int fx)
  206. {
  207. my_stack[++top]=x,dfn[x]=low[x]=++deep;
  208. for(int i=head[x];i;i=edge[i].nxt)
  209. {
  210. int to=edge[i].to;
  211. if(to==fx)continue;
  212. if(!dfn[to])
  213. {
  214. int pre=top;
  215. po_tarjan(to,x);
  216. low[x]=min(low[x],low[to]);
  217. if(dfn[x]<=low[to])
  218. {
  219. src_cnt++,posi[x]++;
  220. int t=0;
  221. while(top!=pre)
  222. {
  223. t=my_stack[top--];
  224. peo[src_cnt].push_back(t);
  225. }
  226. peo[src_cnt].push_back(x);
  227. sort(peo[src_cnt].begin(),peo[src_cnt].end());
  228. }
  229. }else low[x]=min(low[x],dfn[to]);
  230. }
  231. }
  232. void kruscal()
  233. {
  234. sort(e+1,e+m+1);
  235. int tot=0;ll ret=0;
  236. for(int i=1;i<=m;i++)
  237. {
  238. int f1=findf(e[i].l),f2=findf(e[i].r);
  239. if(f1==f2)continue;
  240. f[f1]=f2,tot++,ret+=e[i].v;
  241. if(tot==n-1)break;
  242. }
  243. if(tot==n-1)printf("%lld\n",ret);
  244. else printf("orz\n");
  245. }
  246. void min_dis_spfa(int st)
  247. {
  248. memset(dis,0x3f,sizeof(dis));
  249. dis[st]=0,used[st]=1;
  250. queue <int> M;
  251. M.push(st);
  252. while(!M.empty())
  253. {
  254. int u=M.front();
  255. M.pop();
  256. for(int i=head[u];i;i=edge[i].nxt)
  257. {
  258. int to=edge[i].to;
  259. if(dis[to]>dis[u]+edge[i].val)
  260. {
  261. dis[to]=dis[u]+edge[i].val;
  262. if(!used[to])used[to]=1,M.push(to);
  263. }
  264. }
  265. used[u]=0;
  266. }
  267. for(int i=1;i<=n;i++)
  268. {
  269. if(dis[i]==INF)printf("2147483647 ");
  270. else printf("%lld ",dis[i]);
  271. }
  272. }
  273. void diji(int st)
  274. {
  275. memset(dis,0x3f,sizeof(dis));
  276. dis[st]=0;
  277. priority_queue <node> M;
  278. M.push(node(st,0));
  279. while(!M.empty())
  280. {
  281. node temp=M.top();
  282. M.pop();
  283. int u=temp.p;
  284. if(used[u])continue;
  285. used[u]=1;
  286. for(int i=head[u];i;i=edge[i].nxt)
  287. {
  288. int to=edge[i].to;
  289. if(dis[to]>dis[u]+edge[i].val&&!used[to])dis[to]=dis[u]+edge[i].val,M.push(node(to,dis[to]));
  290. }
  291. }
  292. for(int i=1;i<=n;i++)printf("%lld ",dis[i]);
  293. }
  294. void max_dis_spfa(int st)
  295. {
  296. memset(dis,0,sizeof(dis));
  297. used[st]=1;
  298. dis[st]=src_num[st];
  299. queue <int> M;
  300. M.push(st);
  301. while(!M.empty())
  302. {
  303. int u=M.front();
  304. M.pop();
  305. for(int i=0;i<v[u].size();i++)
  306. {
  307. int to=v[u][i];
  308. if(dis[to]<dis[u]+src_num[to])
  309. {
  310. dis[to]=dis[u]+src_num[to];
  311. if(!used[to])used[to]=1,M.push(to);
  312. }
  313. }
  314. used[u]=0;
  315. }
  316. ll ans=0;
  317. for(int i=1;i<=nu;i++)ans=max(ans,dis[posi[spe[i]]]);
  318. printf("%lld\n",ans);
  319. }
  320. void build_MST()
  321. {
  322. kruscal();
  323. }
  324. void get_min_dis_road()
  325. {
  326. //min_dis_spfa(S);
  327. diji(S);
  328. }
  329. void solve_LCA()
  330. {
  331. tree_dfs(S,S),tree_redfs(S,S,S);
  332. for(int i=1;i<=m;i++)
  333. {
  334. int x,y;
  335. read(x),read(y);
  336. printf("%d\n",link_cut_LCA(x,y));
  337. }
  338. }
  339. void direc_tarjan()//有向图tarjan
  340. {
  341. for(int i=1;i<=n;i++)read(va[i]);
  342. read(S),read(nu);
  343. for(int i=1;i<=nu;i++)read(spe[i]);
  344. for(int i=1;i<=n;i++)if(!dfn[i])di_tarjan(i);
  345. for(int i=1;i<=n;i++)
  346. {
  347. for(int j=head[i];j;j=edge[j].nxt)
  348. {
  349. int to=edge[j].to;
  350. if(posi[i]==posi[to])continue;
  351. else v[posi[i]].push_back(posi[to]);
  352. }
  353. }
  354. max_dis_spfa(posi[S]);
  355. }
  356. void cut_line_tarjan()
  357. {
  358. for(int i=1;i<=n;i++)if(!dfn[i])ed_tarjan(i,-1);
  359. printf("%d ",count_cut_line);
  360. for(int i=1;i<=n;i++)
  361. {
  362. for(int j=head[i];j;j=edge[j].nxt)
  363. {
  364. int to=edge[j].to;
  365. if(posi[i]!=posi[to])inr[posi[to]]++;
  366. }
  367. }
  368. int s=0;
  369. for(int i=1;i<=src_cnt;i++)if(inr[i]==1)s++;
  370. printf("%d\n",(s+1)>>1);
  371. }
  372. void cut_point_tarjan()
  373. {
  374. for(int i=1;i<=n;i++)if(!dfn[i])po_tarjan(i,-1),posi[i]--;
  375. for(int i=1;i<=n;i++)if(posi[i]>=1)cut_point.push_back(i);
  376. printf("%d\n",cut_point.size());
  377. for(int i=0;i<cut_point.size();i++)printf("%d ",cut_point[i]);
  378. printf("\n");
  379. printf("%d\n",src_cnt);
  380. sort(peo+1,peo+src_cnt+1,cmp);
  381. for(int i=1;i<=src_cnt;i++,printf("\n"))for(int j=0;j<peo[i].size();j++)printf("%d ",peo[i][j]);
  382. }
  383. int ide(int x)
  384. {
  385. return x&1?x+1:x-1;
  386. }
  387. bool dinic_bfs()
  388. {
  389. memset(dis,0,sizeof(dis));
  390. memcpy(cur,head,sizeof(head));
  391. dis[S]=1;
  392. queue <int> M;
  393. M.push(S);
  394. while(!M.empty())
  395. {
  396. int u=M.front();
  397. M.pop();
  398. for(int i=head[u];i;i=edge[i].nxt)
  399. {
  400. int to=edge[i].to;
  401. if(edge[i].val&&!dis[to])dis[to]=dis[u]+1,M.push(to);
  402. }
  403. }
  404. return dis[T];
  405. }
  406. ll dinic_dfs(int x,ll lim)
  407. {
  408. if(x==T)return lim;
  409. ll ret=0;
  410. for(int i=cur[x];i;i=edge[i].nxt)
  411. {
  412. cur[x]=i;
  413. int to=edge[i].to;
  414. if(edge[i].val&&dis[to]==dis[x]+1)
  415. {
  416. ll temp=dinic_dfs(to,min(lim,edge[i].val));
  417. if(temp)
  418. {
  419. ret+=temp,lim-=temp;
  420. edge[i].val-=temp,edge[ide(i)].val+=temp;
  421. if(!lim)break;
  422. }
  423. }
  424. }
  425. return ret;
  426. }
  427. ll dinic()
  428. {
  429. ll ans=0;
  430. while(dinic_bfs())ans+=dinic_dfs(S,INF);
  431. return ans;
  432. }
  433. void max_flow()
  434. {
  435. printf("%lld\n",dinic());
  436. }
  437. bool EK_spfa()
  438. {
  439. memset(pre,-1,sizeof(pre));
  440. memset(f,0,sizeof(f));
  441. memset(dis,0x3f,sizeof(dis));
  442. dis[S]=0,lim[S]=INF,used[S]=1;
  443. queue <int> M;
  444. M.push(S);
  445. while(!M.empty())
  446. {
  447. int u=M.front();
  448. M.pop();
  449. for(int i=head[u];i;i=edge[i].nxt)
  450. {
  451. int to=edge[i].to;
  452. if(edge[i].val&&dis[to]>dis[u]+edge[i].pri)
  453. {
  454. dis[to]=dis[u]+edge[i].pri;
  455. pre[to]=i,f[to]=u,lim[to]=min(lim[u],edge[i].val);
  456. if(!used[to])used[to]=1,M.push(to);
  457. }
  458. }
  459. used[u]=0;
  460. }
  461. return pre[T]!=-1;
  462. }
  463. void EK()
  464. {
  465. ll maxf=0,minv=0;
  466. while(EK_spfa())
  467. {
  468. maxf+=lim[T],minv+=dis[T]*lim[T];
  469. int temp=T;
  470. while(temp!=S)edge[pre[temp]].val-=lim[T],edge[ide(pre[temp])].val+=lim[T],temp=f[temp];
  471. }
  472. printf("%lld %lld\n",maxf,minv);
  473. }
  474. void min_cost_max_flow()
  475. {
  476. S=1,T=n;
  477. for(int i=1;i<=m;i++)
  478. {
  479. int x,y;ll z,w;
  480. read(x),read(y),read(z),read(w);
  481. cost_dadd(x,y,z,w);
  482. }
  483. EK();
  484. }
  485. void two_SAT()
  486. {
  487. for(int i=1;i<=m;i++)
  488. {
  489. int x,y,z,w;
  490. read(x),read(y),read(z),read(w);
  491. if(y==1&&w==1)add(x+n,z,0),add(z+n,x,0);
  492. else if(y==1)add(x+n,z+n,0),add(z,x,0);
  493. else if(w==1)add(x,z,0),add(z+n,x+n,0);
  494. else add(x,z+n,0),add(z,x+n,0);
  495. }
  496. n<<=1;
  497. for(int i=1;i<=n;i++)if(!dfn[i])di_tarjan(i);
  498. n>>=1;
  499. for(int i=1;i<=n;i++)if(posi[i]==posi[i+n]){printf("IMPOSSIBLE\n");exit(0);}
  500. printf("POSSIBLE\n");
  501. for(int i=1;i<=n;i++)
  502. {
  503. if(posi[i]<posi[i+n])printf("1 ");
  504. else printf("0 ");
  505. }
  506. printf("\n");
  507. }
  508. bool dfs(int x)
  509. {
  510. for(int i=head[x];i;i=edge[i].nxt)
  511. {
  512. int to=edge[i].to;
  513. if(used[to])continue;
  514. used[to]=1;
  515. if(!f[to]||dfs(f[to])){f[to]=x;return 1;}
  516. }
  517. return 0;
  518. }
  519. int hungary()
  520. {
  521. int ret=0;
  522. for(int i=1;i<=n;i++)
  523. {
  524. for(int j=1;j<=n+m;j++)used[j]=0;
  525. if(dfs(i))ret++;
  526. }
  527. return ret;
  528. }
  529. void two_match()
  530. {
  531. read(n),read(m),read(S);
  532. for(int i=1;i<=S;i++)
  533. {
  534. int x,y;
  535. read(x),read(y);
  536. if(x>n||y>m)continue;
  537. add(x,y+n,0),add(y+n,x,0);
  538. }
  539. printf("%d\n",hungary());
  540. }
  541. void upper_lower_maxflow()
  542. {
  543. int temps=S,tempt=T;
  544. S=n+1,T=n+2;
  545. ll sum=0;
  546. for(int i=1;i<=n;i++)
  547. {
  548. if(fin[i]>fout[i])dadd(S,i,fin[i]-fout[i]),sum+=fin[i]-fout[i];
  549. else dadd(i,T,fout[i]-fin[i]);
  550. }
  551. if(dinic()<sum)printf("please go home to sleep\n");
  552. else S=temps,T=tempt,printf("%lld\n",dinic());
  553. }
  554. void upper_lower_minflow()
  555. {
  556. int temps=S,tempt=T;
  557. S=n+1,T=n+2;
  558. ll sum=0;
  559. for(int i=1;i<=n;i++)
  560. {
  561. if(fin[i]>fout[i])dadd(S,i,fin[i]-fout[i]),sum+=fin[i]-fout[i];
  562. else dadd(i,T,fout[i]-fin[i]);
  563. }
  564. if(dinic()<sum)printf("please go home to sleep\n");
  565. else S=tempt,T=temps,printf("%lld\n",INF-dinic());
  566. }
  567. int main()
  568. {
  569. read(n),read(m),read(S),read(T);
  570. init();
  571. for(int i=1;i<=m;i++)
  572. {
  573. int x,y;ll z,w;
  574. read(x),read(y),read(z),read(w);
  575. fin[y]+=z,fout[x]+=z;
  576. dadd(x,y,w-z);
  577. e[i].l=x,e[i].r=y,e[i].v=z;
  578. }
  579. dadd(T,S,INF);
  580. upper_lower_minflow();
  581. return 0;
  582. }

6.2-SAT

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#define ll long long
using namespace std;
const int maxn=2000005;
const int maxm=5000005;
template <typename T>inline void read(T &x)
{
T f=1,c=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
x=c*f;
}
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
struct Edge
{
int nxt;
int to;
ll val;
ll pri;
}edge[maxm];
struct E
{
int l,r;
ll v;
friend bool operator < (E a,E b)
{
return a.v<b.v;
}
}e[maxm];
struct node
{
int p;ll v;
node (){}
node (int x,ll y):p(x),v(y){}
friend bool operator < (node a,node b)
{
return a.v>b.v;
}
};
int f[maxn];
int head[maxn];
ll dis[maxn];
ll va[maxn];
int dfn[maxn],low[maxn],posi[maxn];
ll src_num[maxn],src_cnt;
int my_stack[maxn],top=0;
int fa[maxn][25];
int dep[maxn];
int spe[maxn],nu;
int siz[maxn],son[maxn],ttop[maxn];
int inr[maxn],our[maxn];
int cur[maxn];
int pre[maxn];
ll lim[maxn];
bool used[maxn];
int cnt=1,deep;
int count_cut_line;
int n,m,S,T;
vector <int> v[maxn];
vector <int> peo[maxn];
vector <int> cut_point;
bool cmp(vector <int> a,vector <int> b)
{
int lim=min(a.size(),b.size());
for(int i=0;i<lim;i++)if(a[i]!=b[i])return a[i]<b[i];
return a.size()<b.size();
}
void init()
{
//for(int i=1;i<=n;i++)f[i]=i,head[i]=0;
cnt=1;
}
void add(int l,int r,ll w)
{
edge[cnt].nxt=head[l];
edge[cnt].to=r;
edge[cnt].val=w;
head[l]=cnt++;
}
void dadd(int l,int r,int w)
{
add(l,r,w),add(r,l,0);
}
void cost_add(int l,int r,ll w,ll p)
{
edge[cnt].nxt=head[l];
edge[cnt].to=r;
edge[cnt].val=w;
edge[cnt].pri=p;
head[l]=cnt++;
}
void cost_dadd(int l,int r,ll w,ll p)
{
cost_add(l,r,w,p),cost_add(r,l,0,-p);
}
int findf(int x)
{
return x==f[x]?x:f[x]=findf(f[x]);
}
void tree_dfs(int x,int fx)
{
dep[x]=dep[fx]+1,siz[x]=1,fa[x][0]=fx;
for(int i=1;i<=20;i++)fa[x][i]=fa[fa[x][i-1]][i-1];
for(int i=head[x];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(to==fx)continue;
tree_dfs(to,x);
siz[x]+=siz[to],son[x]=(siz[son[x]]>siz[to])?son[x]:to;
}
}
void tree_redfs(int x,int topx,int fx)
{
ttop[x]=topx;
if(son[x])tree_redfs(son[x],topx,x);
for(int i=head[x];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(to==fx||to==son[x])continue;
tree_redfs(to,to,x);
}
}
int quick_jump_LCA(int x,int y)//倍增LCA
{
if(dep[x]>dep[y])swap(x,y);
for(int i=20;i>=0;i--)if(dep[fa[y][i]]>=dep[x])y=fa[y][i];
if(x==y)return x;
int ret;
for(int i=20;i>=0;i--)
{
if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
else ret=fa[x][i];
}
return ret;
}
int link_cut_LCA(int x,int y)//树剖LCA
{
while(ttop[x]!=ttop[y])
{
if(dep[ttop[x]]<dep[ttop[y]])swap(x,y);
x=fa[ttop[x]][0];
}
return dep[x]<dep[y]?x:y;
}
void di_tarjan(int x)
{
my_stack[++top]=x,dfn[x]=low[x]=++deep;
for(int i=head[x];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(!dfn[to])
{
di_tarjan(to);
low[x]=min(low[x],low[to]);
}else if(!posi[to])low[x]=min(low[x],dfn[to]);
}
if(dfn[x]==low[x])
{
src_cnt++;
int t=0;
while(t!=x)
{
t=my_stack[top--];
src_num[src_cnt]++;
posi[t]=src_cnt;
}
}
}
void ed_tarjan(int x,int fx)
{
my_stack[++top]=x,dfn[x]=low[x]=++deep;
for(int i=head[x];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(edge[i].val==fx)continue;
if(!dfn[to])
{
ed_tarjan(to,edge[i].val);
low[x]=min(low[x],low[to]);
if(dfn[x]<low[to])count_cut_line++;
}else if(!posi[to])low[x]=min(low[x],dfn[to]);
}
if(dfn[x]==low[x])
{
src_cnt++;
int t=0;
while(t!=x)
{
t=my_stack[top--];
src_num[src_cnt]++;
posi[t]=src_cnt;
}
}
}
void po_tarjan(int x,int fx)
{
my_stack[++top]=x,dfn[x]=low[x]=++deep;
for(int i=head[x];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(to==fx)continue;
if(!dfn[to])
{
int pre=top;
po_tarjan(to,x);
low[x]=min(low[x],low[to]);
if(dfn[x]<=low[to])
{
src_cnt++,posi[x]++;
int t=0;
while(top!=pre)
{
t=my_stack[top--];
peo[src_cnt].push_back(t);
}
peo[src_cnt].push_back(x);
sort(peo[src_cnt].begin(),peo[src_cnt].end());
}
}else low[x]=min(low[x],dfn[to]);
}
}
void kruscal()
{
sort(e+1,e+m+1);
int tot=0;ll ret=0;
for(int i=1;i<=m;i++)
{
int f1=findf(e[i].l),f2=findf(e[i].r);
if(f1==f2)continue;
f[f1]=f2,tot++,ret+=e[i].v;
if(tot==n-1)break;
}
if(tot==n-1)printf("%lld\n",ret);
else printf("orz\n");
}
void min_dis_spfa(int st)
{
memset(dis,0x3f,sizeof(dis));
dis[st]=0,used[st]=1;
queue <int> M;
M.push(st);
while(!M.empty())
{
int u=M.front();
M.pop();
for(int i=head[u];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(dis[to]>dis[u]+edge[i].val)
{
dis[to]=dis[u]+edge[i].val;
if(!used[to])used[to]=1,M.push(to);
}
}
used[u]=0;
}
for(int i=1;i<=n;i++)
{
if(dis[i]==INF)printf("2147483647 ");
else printf("%lld ",dis[i]);
}
}
void diji(int st)
{
memset(dis,0x3f,sizeof(dis));
dis[st]=0;
priority_queue <node> M;
M.push(node(st,0));
while(!M.empty())
{
node temp=M.top();
M.pop();
int u=temp.p;
if(used[u])continue;
used[u]=1;
for(int i=head[u];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(dis[to]>dis[u]+edge[i].val&&!used[to])dis[to]=dis[u]+edge[i].val,M.push(node(to,dis[to]));
}
}
for(int i=1;i<=n;i++)printf("%lld ",dis[i]);
}
void max_dis_spfa(int st)
{
memset(dis,0,sizeof(dis));
used[st]=1;
dis[st]=src_num[st];
queue <int> M;
M.push(st);
while(!M.empty())
{
int u=M.front();
M.pop();
for(int i=0;i<v[u].size();i++)
{
int to=v[u][i];
if(dis[to]<dis[u]+src_num[to])
{
dis[to]=dis[u]+src_num[to];
if(!used[to])used[to]=1,M.push(to);
}
}
used[u]=0;
}
ll ans=0;
for(int i=1;i<=nu;i++)ans=max(ans,dis[posi[spe[i]]]);
printf("%lld\n",ans);
}
void build_MST()
{
kruscal();
}
void get_min_dis_road()
{
//min_dis_spfa(S);
diji(S);
}
void solve_LCA()
{
tree_dfs(S,S),tree_redfs(S,S,S);
for(int i=1;i<=m;i++)
{
int x,y;
read(x),read(y);
printf("%d\n",link_cut_LCA(x,y));
}
}
void direc_tarjan()//有向图tarjan
{
for(int i=1;i<=n;i++)read(va[i]);
read(S),read(nu);
for(int i=1;i<=nu;i++)read(spe[i]);
for(int i=1;i<=n;i++)if(!dfn[i])di_tarjan(i);
for(int i=1;i<=n;i++)
{
for(int j=head[i];j;j=edge[j].nxt)
{
int to=edge[j].to;
if(posi[i]==posi[to])continue;
else v[posi[i]].push_back(posi[to]);
}
}
max_dis_spfa(posi[S]);
}
void cut_line_tarjan()
{
for(int i=1;i<=n;i++)if(!dfn[i])ed_tarjan(i,-1);
printf("%d ",count_cut_line);
for(int i=1;i<=n;i++)
{
for(int j=head[i];j;j=edge[j].nxt)
{
int to=edge[j].to;
if(posi[i]!=posi[to])inr[posi[to]]++;
}
}
int s=0;
for(int i=1;i<=src_cnt;i++)if(inr[i]==1)s++;
printf("%d\n",(s+1)>>1);
}
void cut_point_tarjan()
{
for(int i=1;i<=n;i++)if(!dfn[i])po_tarjan(i,-1),posi[i]--;
for(int i=1;i<=n;i++)if(posi[i]>=1)cut_point.push_back(i);
printf("%d\n",cut_point.size());
for(int i=0;i<cut_point.size();i++)printf("%d ",cut_point[i]);
printf("\n");
printf("%d\n",src_cnt);
sort(peo+1,peo+src_cnt+1,cmp);
for(int i=1;i<=src_cnt;i++,printf("\n"))for(int j=0;j<peo[i].size();j++)printf("%d ",peo[i][j]);
}
int ide(int x)
{
return x&1?x+1:x-1;
}
bool dinic_bfs()
{
memset(dis,0,sizeof(dis));
memcpy(cur,head,sizeof(head));
dis[S]=1;
queue <int> M;
M.push(S);
while(!M.empty())
{
int u=M.front();
M.pop();
for(int i=head[u];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(edge[i].val&&!dis[to])dis[to]=dis[u]+1,M.push(to);
}
}
return dis[T];
}
ll dinic_dfs(int x,ll lim)
{
if(x==T)return lim;
ll ret=0;
for(int i=cur[x];i;i=edge[i].nxt)
{
cur[x]=i;
int to=edge[i].to;
if(edge[i].val&&dis[to]==dis[x]+1)
{
ll temp=dinic_dfs(to,min(lim,edge[i].val));
if(temp)
{
ret+=temp,lim-=temp;
edge[i].val-=temp,edge[ide(i)].val+=temp;
if(!lim)break;
}
}
}
return ret;
}
ll dinic()
{
ll ans=0;
while(dinic_bfs())ans+=dinic_dfs(S,INF);
return ans;
}
void max_flow()
{
printf("%lld\n",dinic());
}
bool EK_spfa()
{
memset(pre,-1,sizeof(pre));
memset(f,0,sizeof(f));
memset(dis,0x3f,sizeof(dis));
dis[S]=0,lim[S]=INF,used[S]=1;
queue <int> M;
M.push(S);
while(!M.empty())
{
int u=M.front();
M.pop();
for(int i=head[u];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(edge[i].val&&dis[to]>dis[u]+edge[i].pri)
{
dis[to]=dis[u]+edge[i].pri;
pre[to]=i,f[to]=u,lim[to]=min(lim[u],edge[i].val);
if(!used[to])used[to]=1,M.push(to);
}
}
used[u]=0;
}
return pre[T]!=-1;
}
void EK()
{
ll maxf=0,minv=0;
while(EK_spfa())
{
maxf+=lim[T],minv+=dis[T]*lim[T];
int temp=T;
while(temp!=S)edge[pre[temp]].val-=lim[T],edge[ide(pre[temp])].val+=lim[T],temp=f[temp];
}
printf("%lld %lld\n",maxf,minv);
}
void min_cost_max_flow()
{
S=1,T=n;
for(int i=1;i<=m;i++)
{
int x,y;ll z,w;
read(x),read(y),read(z),read(w);
cost_dadd(x,y,z,w);
}
EK();
}
void two_SAT()
{
for(int i=1;i<=m;i++)
{
int x,y,z,w;
read(x),read(y),read(z),read(w);
if(y==1&&w==1)add(x+n,z,0),add(z+n,x,0);
else if(y==1)add(x+n,z+n,0),add(z,x,0);
else if(w==1)add(x,z,0),add(z+n,x+n,0);
else add(x,z+n,0),add(z,x+n,0);
}
n<<=1;
for(int i=1;i<=n;i++)if(!dfn[i])di_tarjan(i);
n>>=1;
for(int i=1;i<=n;i++)if(posi[i]==posi[i+n]){printf("IMPOSSIBLE\n");exit(0);}
printf("POSSIBLE\n");
for(int i=1;i<=n;i++)
{
if(posi[i]<posi[i+n])printf("1 ");
else printf("0 ");
}
printf("\n");
}
int main()
{
read(n),read(m)//,read(S),read(T);
init();
two_SAT();
return 0;
for(int i=1;i<=m;i++)
{
int x,y;ll z;
read(x),read(y),read(z);
dadd(x,y,z);//,add(y,x,z);
e[i].l=x,e[i].r=y,e[i].v=z;
}
return 0;
}

7.二分图匹配(匈牙利)

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#define ll long long
using namespace std;
const int maxn=2000005;
const int maxm=5000005;
template <typename T>inline void read(T &x)
{
T f=1,c=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
x=c*f;
}
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
struct Edge
{
int nxt;
int to;
ll val;
ll pri;
}edge[maxm];
struct E
{
int l,r;
ll v;
friend bool operator < (E a,E b)
{
return a.v<b.v;
}
}e[maxm];
struct node
{
int p;ll v;
node (){}
node (int x,ll y):p(x),v(y){}
friend bool operator < (node a,node b)
{
return a.v>b.v;
}
};
int f[maxn];
int head[maxn];
ll dis[maxn];
ll va[maxn];
int dfn[maxn],low[maxn],posi[maxn];
ll src_num[maxn],src_cnt;
int my_stack[maxn],top=0;
int fa[maxn][25];
int dep[maxn];
int spe[maxn],nu;
int siz[maxn],son[maxn],ttop[maxn];
int inr[maxn],our[maxn];
int cur[maxn];
int pre[maxn];
ll lim[maxn];
bool used[maxn];
int cnt=1,deep;
int count_cut_line;
int n,m,S,T;
vector <int> v[maxn];
vector <int> peo[maxn];
vector <int> cut_point;
bool cmp(vector <int> a,vector <int> b)
{
int lim=min(a.size(),b.size());
for(int i=0;i<lim;i++)if(a[i]!=b[i])return a[i]<b[i];
return a.size()<b.size();
}
void init()
{
//for(int i=1;i<=n;i++)f[i]=i,head[i]=0;
cnt=1;
}
void add(int l,int r,ll w)
{
edge[cnt].nxt=head[l];
edge[cnt].to=r;
edge[cnt].val=w;
head[l]=cnt++;
}
void dadd(int l,int r,int w)
{
add(l,r,w),add(r,l,0);
}
void cost_add(int l,int r,ll w,ll p)
{
edge[cnt].nxt=head[l];
edge[cnt].to=r;
edge[cnt].val=w;
edge[cnt].pri=p;
head[l]=cnt++;
}
void cost_dadd(int l,int r,ll w,ll p)
{
cost_add(l,r,w,p),cost_add(r,l,0,-p);
}
int findf(int x)
{
return x==f[x]?x:f[x]=findf(f[x]);
}
void tree_dfs(int x,int fx)
{
dep[x]=dep[fx]+1,siz[x]=1,fa[x][0]=fx;
for(int i=1;i<=20;i++)fa[x][i]=fa[fa[x][i-1]][i-1];
for(int i=head[x];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(to==fx)continue;
tree_dfs(to,x);
siz[x]+=siz[to],son[x]=(siz[son[x]]>siz[to])?son[x]:to;
}
}
void tree_redfs(int x,int topx,int fx)
{
ttop[x]=topx;
if(son[x])tree_redfs(son[x],topx,x);
for(int i=head[x];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(to==fx||to==son[x])continue;
tree_redfs(to,to,x);
}
}
int quick_jump_LCA(int x,int y)//倍增LCA
{
if(dep[x]>dep[y])swap(x,y);
for(int i=20;i>=0;i--)if(dep[fa[y][i]]>=dep[x])y=fa[y][i];
if(x==y)return x;
int ret;
for(int i=20;i>=0;i--)
{
if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
else ret=fa[x][i];
}
return ret;
}
int link_cut_LCA(int x,int y)//树剖LCA
{
while(ttop[x]!=ttop[y])
{
if(dep[ttop[x]]<dep[ttop[y]])swap(x,y);
x=fa[ttop[x]][0];
}
return dep[x]<dep[y]?x:y;
}
void di_tarjan(int x)
{
my_stack[++top]=x,dfn[x]=low[x]=++deep;
for(int i=head[x];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(!dfn[to])
{
di_tarjan(to);
low[x]=min(low[x],low[to]);
}else if(!posi[to])low[x]=min(low[x],dfn[to]);
}
if(dfn[x]==low[x])
{
src_cnt++;
int t=0;
while(t!=x)
{
t=my_stack[top--];
src_num[src_cnt]++;
posi[t]=src_cnt;
}
}
}
void ed_tarjan(int x,int fx)
{
my_stack[++top]=x,dfn[x]=low[x]=++deep;
for(int i=head[x];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(edge[i].val==fx)continue;
if(!dfn[to])
{
ed_tarjan(to,edge[i].val);
low[x]=min(low[x],low[to]);
if(dfn[x]<low[to])count_cut_line++;
}else if(!posi[to])low[x]=min(low[x],dfn[to]);
}
if(dfn[x]==low[x])
{
src_cnt++;
int t=0;
while(t!=x)
{
t=my_stack[top--];
src_num[src_cnt]++;
posi[t]=src_cnt;
}
}
}
void po_tarjan(int x,int fx)
{
my_stack[++top]=x,dfn[x]=low[x]=++deep;
for(int i=head[x];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(to==fx)continue;
if(!dfn[to])
{
int pre=top;
po_tarjan(to,x);
low[x]=min(low[x],low[to]);
if(dfn[x]<=low[to])
{
src_cnt++,posi[x]++;
int t=0;
while(top!=pre)
{
t=my_stack[top--];
peo[src_cnt].push_back(t);
}
peo[src_cnt].push_back(x);
sort(peo[src_cnt].begin(),peo[src_cnt].end());
}
}else low[x]=min(low[x],dfn[to]);
}
}
void kruscal()
{
sort(e+1,e+m+1);
int tot=0;ll ret=0;
for(int i=1;i<=m;i++)
{
int f1=findf(e[i].l),f2=findf(e[i].r);
if(f1==f2)continue;
f[f1]=f2,tot++,ret+=e[i].v;
if(tot==n-1)break;
}
if(tot==n-1)printf("%lld\n",ret);
else printf("orz\n");
}
void min_dis_spfa(int st)
{
memset(dis,0x3f,sizeof(dis));
dis[st]=0,used[st]=1;
queue <int> M;
M.push(st);
while(!M.empty())
{
int u=M.front();
M.pop();
for(int i=head[u];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(dis[to]>dis[u]+edge[i].val)
{
dis[to]=dis[u]+edge[i].val;
if(!used[to])used[to]=1,M.push(to);
}
}
used[u]=0;
}
for(int i=1;i<=n;i++)
{
if(dis[i]==INF)printf("2147483647 ");
else printf("%lld ",dis[i]);
}
}
void diji(int st)
{
memset(dis,0x3f,sizeof(dis));
dis[st]=0;
priority_queue <node> M;
M.push(node(st,0));
while(!M.empty())
{
node temp=M.top();
M.pop();
int u=temp.p;
if(used[u])continue;
used[u]=1;
for(int i=head[u];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(dis[to]>dis[u]+edge[i].val&&!used[to])dis[to]=dis[u]+edge[i].val,M.push(node(to,dis[to]));
}
}
for(int i=1;i<=n;i++)printf("%lld ",dis[i]);
}
void max_dis_spfa(int st)
{
memset(dis,0,sizeof(dis));
used[st]=1;
dis[st]=src_num[st];
queue <int> M;
M.push(st);
while(!M.empty())
{
int u=M.front();
M.pop();
for(int i=0;i<v[u].size();i++)
{
int to=v[u][i];
if(dis[to]<dis[u]+src_num[to])
{
dis[to]=dis[u]+src_num[to];
if(!used[to])used[to]=1,M.push(to);
}
}
used[u]=0;
}
ll ans=0;
for(int i=1;i<=nu;i++)ans=max(ans,dis[posi[spe[i]]]);
printf("%lld\n",ans);
}
void build_MST()
{
kruscal();
}
void get_min_dis_road()
{
//min_dis_spfa(S);
diji(S);
}
void solve_LCA()
{
tree_dfs(S,S),tree_redfs(S,S,S);
for(int i=1;i<=m;i++)
{
int x,y;
read(x),read(y);
printf("%d\n",link_cut_LCA(x,y));
}
}
void direc_tarjan()//有向图tarjan
{
for(int i=1;i<=n;i++)read(va[i]);
read(S),read(nu);
for(int i=1;i<=nu;i++)read(spe[i]);
for(int i=1;i<=n;i++)if(!dfn[i])di_tarjan(i);
for(int i=1;i<=n;i++)
{
for(int j=head[i];j;j=edge[j].nxt)
{
int to=edge[j].to;
if(posi[i]==posi[to])continue;
else v[posi[i]].push_back(posi[to]);
}
}
max_dis_spfa(posi[S]);
}
void cut_line_tarjan()
{
for(int i=1;i<=n;i++)if(!dfn[i])ed_tarjan(i,-1);
printf("%d ",count_cut_line);
for(int i=1;i<=n;i++)
{
for(int j=head[i];j;j=edge[j].nxt)
{
int to=edge[j].to;
if(posi[i]!=posi[to])inr[posi[to]]++;
}
}
int s=0;
for(int i=1;i<=src_cnt;i++)if(inr[i]==1)s++;
printf("%d\n",(s+1)>>1);
}
void cut_point_tarjan()
{
for(int i=1;i<=n;i++)if(!dfn[i])po_tarjan(i,-1),posi[i]--;
for(int i=1;i<=n;i++)if(posi[i]>=1)cut_point.push_back(i);
printf("%d\n",cut_point.size());
for(int i=0;i<cut_point.size();i++)printf("%d ",cut_point[i]);
printf("\n");
printf("%d\n",src_cnt);
sort(peo+1,peo+src_cnt+1,cmp);
for(int i=1;i<=src_cnt;i++,printf("\n"))for(int j=0;j<peo[i].size();j++)printf("%d ",peo[i][j]);
}
int ide(int x)
{
return x&1?x+1:x-1;
}
bool dinic_bfs()
{
memset(dis,0,sizeof(dis));
memcpy(cur,head,sizeof(head));
dis[S]=1;
queue <int> M;
M.push(S);
while(!M.empty())
{
int u=M.front();
M.pop();
for(int i=head[u];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(edge[i].val&&!dis[to])dis[to]=dis[u]+1,M.push(to);
}
}
return dis[T];
}
ll dinic_dfs(int x,ll lim)
{
if(x==T)return lim;
ll ret=0;
for(int i=cur[x];i;i=edge[i].nxt)
{
cur[x]=i;
int to=edge[i].to;
if(edge[i].val&&dis[to]==dis[x]+1)
{
ll temp=dinic_dfs(to,min(lim,edge[i].val));
if(temp)
{
ret+=temp,lim-=temp;
edge[i].val-=temp,edge[ide(i)].val+=temp;
if(!lim)break;
}
}
}
return ret;
}
ll dinic()
{
ll ans=0;
while(dinic_bfs())ans+=dinic_dfs(S,INF);
return ans;
}
void max_flow()
{
printf("%lld\n",dinic());
}
bool EK_spfa()
{
memset(pre,-1,sizeof(pre));
memset(f,0,sizeof(f));
memset(dis,0x3f,sizeof(dis));
dis[S]=0,lim[S]=INF,used[S]=1;
queue <int> M;
M.push(S);
while(!M.empty())
{
int u=M.front();
M.pop();
for(int i=head[u];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(edge[i].val&&dis[to]>dis[u]+edge[i].pri)
{
dis[to]=dis[u]+edge[i].pri;
pre[to]=i,f[to]=u,lim[to]=min(lim[u],edge[i].val);
if(!used[to])used[to]=1,M.push(to);
}
}
used[u]=0;
}
return pre[T]!=-1;
}
void EK()
{
ll maxf=0,minv=0;
while(EK_spfa())
{
maxf+=lim[T],minv+=dis[T]*lim[T];
int temp=T;
while(temp!=S)edge[pre[temp]].val-=lim[T],edge[ide(pre[temp])].val+=lim[T],temp=f[temp];
}
printf("%lld %lld\n",maxf,minv);
}
void min_cost_max_flow()
{
S=1,T=n;
for(int i=1;i<=m;i++)
{
int x,y;ll z,w;
read(x),read(y),read(z),read(w);
cost_dadd(x,y,z,w);
}
EK();
}
void two_SAT()
{
for(int i=1;i<=m;i++)
{
int x,y,z,w;
read(x),read(y),read(z),read(w);
if(y==1&&w==1)add(x+n,z,0),add(z+n,x,0);
else if(y==1)add(x+n,z+n,0),add(z,x,0);
else if(w==1)add(x,z,0),add(z+n,x+n,0);
else add(x,z+n,0),add(z,x+n,0);
}
n<<=1;
for(int i=1;i<=n;i++)if(!dfn[i])di_tarjan(i);
n>>=1;
for(int i=1;i<=n;i++)if(posi[i]==posi[i+n]){printf("IMPOSSIBLE\n");exit(0);}
printf("POSSIBLE\n");
for(int i=1;i<=n;i++)
{
if(posi[i]<posi[i+n])printf("1 ");
else printf("0 ");
}
printf("\n");
}
bool dfs(int x)
{
for(int i=head[x];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(used[to])continue;
used[to]=1;
if(!f[to]||dfs(f[to])){f[to]=x;return 1;}
}
return 0;
}
int hungary()
{
int ret=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n+m;j++)used[j]=0;
if(dfs(i))ret++;
}
return ret;
}
void two_match()
{
read(n),read(m),read(S);
for(int i=1;i<=S;i++)
{
int x,y;
read(x),read(y);
if(x>n||y>m)continue;
add(x,y+n,0),add(y+n,x,0);
}
printf("%d\n",hungary());
}
int main()
{
two_match();
return 0;
read(n),read(m);//,read(S),read(T);
init();
for(int i=1;i<=m;i++)
{
int x,y;ll z;
read(x),read(y),read(z);
dadd(x,y,z);//,add(y,x,z);
e[i].l=x,e[i].r=y,e[i].v=z;
}
return 0;
}

NOI模板复习组——图论部分的更多相关文章

  1. wawawa8的模板复习计划

    wawawa8的模板复习计划 数据结构 //手写堆 [link][https://www.luogu.org/problemnew/show/P3378] //并查集 [link][https://w ...

  2. NOIP前的模板复习和注意事项

    联赛除去今天刚好只有一个星期了,最后一个星期也很关键,要吃好睡好保持心情愉悦.当然也免不了最后的复习计划. 首先是模板,之前还有很多模板没有复习到,这些东西是一定要落实到位的. 每天往后面写一点... ...

  3. 模板复习【updating】

    马上就要noi了……可能滚粗已经稳了……但是还是要复习模板啊 LCT: bzoj2049 1A 7min # include <stdio.h> # include <string. ...

  4. NOIP专题复习3 图论-强连通分量

    目录 一.知识概述 二.典型例题 1.[HAOI2006]受欢迎的牛 2.校园网络[[USACO]Network of Schools加强版] 三.算法分析 (一)Tarjan算法 (二)解决问题 四 ...

  5. NOIP专题复习2 图论-生成树

    目录 一.知识概述 二.典型例题 1.口袋的天空 三.算法分析 (一)Prim算法 (二)Kruskal 四.算法应用 1.[NOIP2013]货车运输 五.算法拓展 1977: [BeiJing20 ...

  6. NOIP专题复习1 图论-最短路

    一.知识概述 今天我们要复习的内容是图论中的最短路算法,我们在这里讲3种最短路求法,分别是:floyd,dijkstra,spfa. 那么我们从几道例题来切入今天讲解的算法. 二.典型例题 1.热浪 ...

  7. noip模板复习

    自己敲模板还是有很多容易错的地方 写在注释里面了 LCA #include<bits/stdc++.h> #define REP(i, a, b) for(register int i = ...

  8. NOI ONLINE 入门组 魔法 矩阵快速幂

    做了这道题我才发现NOI入门组!=NOIP普及组 题目链接 https://www.luogu.com.cn/problem/P6190 题意 给出一张有向图,你有K次机会可以反转一条边的边权,即让它 ...

  9. CSP-S 赛前模板复习

    快读模板 这个连算法都算不上... inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9') ...

  10. NOI Online 提高组 题解

    来补坑了-- 个人认为三道题难度差不多-- 还有要说一嘴,为啥我在其他网站代码都好好的,复制到 cnblogs 上 Tab 就成 8 空格了?不过也懒得改了. T1 序列 首先,遇到这种加一减一还带附 ...

随机推荐

  1. DOS命令操作

    打开CMD的方式 1.开始+系统+命令提示符 2.Win键+R 输入CMD打开控制台(推荐使用) 3.在任意的文件夹下面,按住shift+鼠标右键点击,在此处打开命令行窗口 4.资源管理器的地址栏前面 ...

  2. docker+react+nginx部署

    一.准备工作 1.先确保项目可以正常运行. 2.如果拉代码到Linux下进行打包,注意node版本,我就是版本不同,yarn build一直不成功. 3.找一个nginx的配置文件nginx.conf ...

  3. 模拟ATM系统 —— 用户存款、取款、转账、修改密码和销户功能

    接着上一篇: 5.用户存款功能 分析: *存款就是拿到当前账户对象 *然后让用户输入存款的金额 *调用账户对象的setMoney方法将账户余额修改成存钱后的余额 *存款后需要查询当前账户信息,确认是否 ...

  4. Arch安装记录(BIOS+GPT)

    尝试了下arch安装,并且尝试了下不长用的BIOS + GPT组合.都说arch的wiki强,确实很强,可惜自己的水平看不了多少. https://wiki.archlinux.org/index.p ...

  5. unity Android路径的相关部分代码

    using System; using System.Collections; using System.Collections.Generic; using System.IO; using Uni ...

  6. 常用IBatis属性

    <?xml version="1.0" encoding="utf-8" ?> <sqlMap namespace="GoodDet ...

  7. git的基本操作(一)

    pwd: 显示当前所在的目录路径 ls: 列出当前目录的所有文件 touch: 新建一个文件 rm:删除一个文件 mkdir:新建一个目录 rm -r:删除一个目录 mv:移动一个文件到另一个文件中 ...

  8. android 打包任务在gradle中

    //打包任务task makexxxxxxJar(type: Jar) { //指定生成的jar名 baseName xxxxxx //从哪里打包class文件 from('build/interme ...

  9. Solution Set - 杭电多校 2022 Day2 一句话题解

    A:看了题就很容易想到虚树吧,建出虚树后考虑整体扫一遍虚树,注意到这是一棵根向树,那么统计其实十分简单,将对 \(C\) 类节点的标记下放,\(A,B\) 类节点同时上传,如果在 DFS 的过程中发现 ...

  10. ABAP 报表的两种下钻功能

    在报表开发中往往会由需求要求跳转,SAP中提供了一些下钻的方式. 这里主要介绍两种 submit 和 call transaction submit 引用的是报表名称,以自开发报表居多 call tr ...