【日记7.20】复习图论知识
现在开始的复习,想到什么写点儿什么吧。
1,网络流方面
sap,注意调整n的大小,因为加入了源汇点。cur数组的修改,枚举边的时候的循环,都要注意。
2,LCA
用的是离线的算法Tarjan,也就是说先全部读入然后处理,下边的文章写得很好。重点是对dfs的理解和对并查集的利用
我是看的这个博客才彻底明白的,http://blog.163.com/myq_952/blog/static/8639063201132811281700/
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 *Prob : Hdu 2586 3 *Sol : LCA 4 *Data : 2012-7-20 5 */ 6 7 #include <cstdio> 8 #include <cstring> 9 10 #define MaxM 10000 11 #define MaxN 40001 12 13 using namespace std; 14 15 struct node { 16 int y,v,next; 17 } e[MaxN*2]; 18 bool v[MaxN]; 19 int a[MaxN],dis[MaxN],f[MaxN]; 20 int x[MaxM],y[MaxM],z[MaxM]; 21 22 int n,m,tot = 0; 23 24 void insert(int x,int y,int v) 25 { 26 e[tot].y = y; e[tot].v = v; 27 e[tot].next = a[x]; a[x] = tot; 28 } 29 30 int find(int x) 31 { 32 if (f[x]==x) return f[x]; 33 else return f[x]=find(f[x]); 34 } 35 36 void tarjan(int k) 37 { 38 int i; 39 v[k] = true; f[k] = k; 40 for (int i=1; i<=m; i++) { 41 if (x[i]==k && v[y[i]]) z[i] = find(y[i]); 42 if (y[i]==k && v[x[i]]) z[i] = find(x[i]); 43 } 44 for (int i=a[k]; i; i = e[i].next) { 45 int tmn = e[i].y; 46 if (!v[tmn]) { 47 dis[tmn] = dis[k] + e[i].v; 48 tarjan(tmn); 49 f[tmn] = k; 50 } 51 } 52 } 53 54 int main() 55 { 56 freopen("a.in","r",stdin); 57 freopen("a.out","w",stdout); 58 59 int t,a,b,c; 60 scanf("%d",&t); 61 while (t--) { 62 scanf("%d%d",&n,&m); 63 for (int i=1; i<n; i++) { 64 scanf("%d%d%d",&a,&b,&c); 65 tot++; insert(a,b,c); 66 tot++; insert(b,a,c); 67 } 68 memset(x,0,sizeof(x)); 69 memset(y,0,sizeof(y)); 70 memset(z,0,sizeof(z)); 71 for (int i=1; i<=m; i++) 72 scanf("%d%d",&x[i],&y[i]); 73 74 memset(v,false,sizeof(v)); 75 memset(dis,0,sizeof(dis)); 76 dis[1] = 0; 77 tarjan(1); 78 79 for (int i=1; i<=m; i++) 80 printf("%d\n",dis[x[i]]+dis[y[i]]-2*dis[z[i]]); 81 scanf("\n"); 82 } 83 84 fclose(stdin); fclose(stdout); 85 86 }
最基础的题目了,不一遍AC就不好意思说自己看懂了Lca
3,基础的算法
spfa注意出队入队的bool数组的改变,kruskal并查集的利用。
4,图的割顶桥和强连通分量
用的都是Tarjan,没什么难得,注意dfn和low数组的利用就好。