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.网络流

最大流:

#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;
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[5000005];
struct E
{
int l,r;
ll v;
friend bool operator < (E a,E b)
{
return a.v<b.v;
}
}e[5000005];
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[500005];
int head[500005];
ll dis[500005];
ll va[500005];
int dfn[500005],low[500005],posi[500005];
ll src_num[500005],src_cnt;
int my_stack[500005],top=0;
int fa[500005][25];
int dep[500005];
int spe[500005],nu;
int siz[500005],son[500005],ttop[500005];
int inr[500005],our[500005];
int cur[500005];
ll lim[500005];
bool used[500005];
int cnt=1,deep;
int count_cut_line;
int n,m,S,T;
vector <int> v[500005];
vector <int> peo[500005];
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);
}
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]+=va[t];
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());
}
int main()
{
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;
}
max_flow();
return 0;
}

费用流:

#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;
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[5000005];
struct E
{
int l,r;
ll v;
friend bool operator < (E a,E b)
{
return a.v<b.v;
}
}e[5000005];
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[500005];
int head[500005];
ll dis[500005];
ll va[500005];
int dfn[500005],low[500005],posi[500005];
ll src_num[500005],src_cnt;
int my_stack[500005],top=0;
int fa[500005][25];
int dep[500005];
int spe[500005],nu;
int siz[500005],son[500005],ttop[500005];
int inr[500005],our[500005];
int cur[500005];
int pre[500005];
ll lim[500005];
bool used[500005];
int cnt=1,deep;
int count_cut_line;
int n,m,S,T;
vector <int> v[500005];
vector <int> peo[500005];
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]+=va[t];
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();
}
int main()
{
read(n),read(m);//,read(S),read(T);
init();
min_cost_max_flow();
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;
}
max_flow();
return 0;
}

有源汇上下界最大流

#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];
ll fin[maxn],fout[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,ll 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());
}
void upper_lower_maxflow()
{
int temps=S,tempt=T;
S=n+1,T=n+2;
ll sum=0;
for(int i=1;i<=n;i++)
{
if(fin[i]>fout[i])dadd(S,i,fin[i]-fout[i]),sum+=fin[i]-fout[i];
else dadd(i,T,fout[i]-fin[i]);
}
if(dinic()<sum)printf("please go home to sleep\n");
else S=temps,T=tempt,printf("%lld\n",dinic());
}
void upper_lower_minflow()
{
int temps=S,tempt=T;
S=n+1,T=n+2;
ll sum=0;
for(int i=1;i<=n;i++)
{
if(fin[i]>fout[i])dadd(S,i,fin[i]-fout[i]),sum+=fin[i]-fout[i];
else dadd(i,T,fout[i]-fin[i]);
}
if(dinic()<sum)printf("please go home to sleep\n");
else S=tempt,T=temps,printf("%lld\n",INF-dinic());
}
int main()
{
read(n),read(m),read(S),read(T);
init();
for(int i=1;i<=m;i++)
{
int x,y;ll z,w;
read(x),read(y),read(z),read(w);
fin[y]+=z,fout[x]+=z;
dadd(x,y,w-z);
e[i].l=x,e[i].r=y,e[i].v=z;
}
dadd(T,S,INF);
upper_lower_maxflow();
return 0;
}

有源汇上下界最小流

#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];
ll fin[maxn],fout[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,ll 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());
}
void upper_lower_maxflow()
{
int temps=S,tempt=T;
S=n+1,T=n+2;
ll sum=0;
for(int i=1;i<=n;i++)
{
if(fin[i]>fout[i])dadd(S,i,fin[i]-fout[i]),sum+=fin[i]-fout[i];
else dadd(i,T,fout[i]-fin[i]);
}
if(dinic()<sum)printf("please go home to sleep\n");
else S=temps,T=tempt,printf("%lld\n",dinic());
}
void upper_lower_minflow()
{
int temps=S,tempt=T;
S=n+1,T=n+2;
ll sum=0;
for(int i=1;i<=n;i++)
{
if(fin[i]>fout[i])dadd(S,i,fin[i]-fout[i]),sum+=fin[i]-fout[i];
else dadd(i,T,fout[i]-fin[i]);
}
if(dinic()<sum)printf("please go home to sleep\n");
else S=tempt,T=temps,printf("%lld\n",INF-dinic());
}
int main()
{
read(n),read(m),read(S),read(T);
init();
for(int i=1;i<=m;i++)
{
int x,y;ll z,w;
read(x),read(y),read(z),read(w);
fin[y]+=z,fout[x]+=z;
dadd(x,y,w-z);
e[i].l=x,e[i].r=y,e[i].v=z;
}
dadd(T,S,INF);
upper_lower_minflow();
return 0;
}

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. uniapp引入微信小程序自定义视频组件--记录

    官方文档:https://zh.uniapp.dcloud.io/tutorial/miniprogram-subject.html 在 pages.json同级目录下 创建目录和文件: wxcomp ...

  2. 内存模型--共享、JMM

    Balking 指令重排

  3. 杂:使用Shell判断文件换行符(LF/CRLF)

    前提:文件最后一行有换行符 第一步:以二进制方式取得文件最后两个byte.last2=`tail -c 2 <your_file> | od -x -A n` 第二步:判断最后两个byte ...

  4. C#中延迟初始化实现原理的一点浅见。

    定义 延迟初始化:一个对象的延迟初始化意味着它的创建被推迟到它第一次使用.(对于本主题,延迟初始化和延迟实例化是同义词.)延迟初始化主要用于提高性能.避免浪费计算和减少程序内存需求. 用法及简单介绍 ...

  5. WPF materialDesign 锁屏后界面卡死问题解决

    materialDesign的一个缓存机制问题,在xaml文件中Window属性添加一行: materialDesign:ShadowAssist.CacheMode="{x:Null}&q ...

  6. 力扣1143. 最长公共子序列(dp)

    给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度.如果不存在 公共子序列 ,返回 0 . 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符 ...

  7. 如何在winform打包时带上sqlite数据库

    sqlite数据库下载及使用:https://blog.csdn.net/Yyuanyuxin/article/details/105508886sqlite数据库可视化工具-- DB.Browser ...

  8. 登录他人mysql

    //登录参数:mysql -u用户名 -p密码 -h要连接的mysql服务器的ip地址(默认127.0.0.1) -P端口号(默认3306)

  9. office2016word打开总是提示安全模式

    突然打开word和Excel提示是否使用安全模式,如果选择否就自动退出office,选择是进入后,编辑一下也会自己退出,非常郁闷. 之后上网查看,尝试了许多: 1.win+R 运行%appdata%\ ...

  10. BIP 两个请求成功后,才能做某一件事

    //保存前校验 let SetXStatus = 0; viewModel.on("beforeSave", function (args) { let _this = this; ...