近期呢,学习图论也有一段时间了。想要说的是,首先对自己的刷题速度十分不满。差不多一个星期过去了,只刷了六道图论的题((⊙o⊙)…)。这里来一个简单的总结吧。
注意点大致有四个。
一、一个库的使用。图论的题一般都是使用数组解决,所以要使用memset这个函数,那么就不能忘记加上去#include<cstring>这个库。
二、有向图和无向图的区分。关于有向图,我们在对二维数组赋值的时候一次就可以了。而对于无向图,则必须颠倒过来再次进行赋值。(因为这个问题耽误了不少时间~~尴尬)
三、对于题意的分析和理解。这一点十分重要。我们写图论的题一般都是先存储再搜索,而不同的题型所需要的方法也不同。比如说我写的P1209这道题,题目要求每次输出的数据都是较小的,并且数据的范围也比较小,这时候用邻接矩阵就十分的方便了。而比如说警察抓小偷的那道题,数据范围过大,这时候就不得不使用邻接表来存储信息。同时根据情况的不同,也要选择不同的搜索方式。比较经典的就是深搜和广搜。
四、这是今天刘老师来机房讲的。那就是当自己的算法在头脑比较清晰,而数据又过不了的时候,千万不要尝试着去调试程序。这个效率太慢,而且极其容易混淆,以至于一遍一遍得重新过。我以前就是经常做这样的事,所以刷题速度很慢,有时候一天才一道题。最好的办法就是把代码删了,然后重新打一遍,这个方法十分受用,往往我们在重打代码的过程中,一些微小的难以找到的错误就改正过来了。
以上便是我对今天的总结。
void dfs(int k) { for(int i=1;i<=maxx;i++) { if(a[k][i]!=0) { a[k][i]--;a[i][k]--; dfs(i); } if(sum==F) {x=k;prin();exit(0);} }sum++;c[sum]=k; }//回溯
void insert(int x,int y) { e[++len].next=lin[x]; lin[x]=len; e[len].yy=y; } for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y); insert(x,y); insert(y,x); }//邻接表的读入
void dfs(int k) { int head=0; int tail=1; q[1]=k; while(head++<tail) { for(int i=lin[q[head]];i;i=e[i].next) { if(!ff[e[i].yy]) { ff[e[i].yy]=1; q[++tail]=e[i].yy; } } } } int main() { ~~~ for(int i=1;i<=n;i++) if(!ff[i]) { dfs(i);sum++;} }//广搜
void dfs(int k) { for(int i=lin[k];i;i=e[i].next) { if(!ff[e[i].yy]) {ff[e[i].yy]=1;dfs(e[i].yy);} } } for(int i=1;i<=n;i++) if(!ff[i]) { dfs(i);sum++;}//深搜