摘要: DFS模拟,然后srch(i, j)表示输出用i, j组成的树的后序遍历,返回0就是都是0,1就是都是1,2就是0,1都有。。#include <stdio.h>#include <string.h>#include <stdlib.h>char str[1025];char put[3] = {'B', 'I' ,'F'};int srch(int start, int end){ int i, j; if(start == end){ printf("%c", put[str[start 阅读全文
posted @ 2011-08-07 23:46 zqynux 阅读(1469) 评论(0) 推荐(0) 编辑
摘要: 数论题目?也许把,不过暴搜在TYVJ的平台上能用(评测机太好了!)因为那个数论的在考试里的话,打死我也是想不到的,所以就模拟了,果断不太多废话:#include <stdio.h>#include <stdlib.h>int pow_(int a, int b){ if(b == 0){ return 1; } if(b & 1){ return (pow_((a * a) % 7, b / 2) * a) % 7; }else{ return (pow_((a * a) % 7, b / 2)) % 7; }}int main(int argc, char * 阅读全文
posted @ 2011-08-07 23:05 zqynux 阅读(229) 评论(0) 推荐(0) 编辑
摘要: 常见的(我见过的)强连通分量的三种算法有:1. Kosaraju算法(双DFS)2.Tarjan算法 3.Gabow一.Kosaraju算法算法的核心实现是,首先DFS一遍,得到一个DFS森林,在此过程中得到所有点的拓扑序列(按结束时间由高到低),之后我们建一个反向图,按反拓扑序(结束时间由高到低)进行第二次DFS,则此时得到的每一棵树都是一个强连通分量,这个画个图演示一下比较好理解,严格证明还是参考算法导论340页较好,感性的认识是,假定我们有C1,C2两个强连通分量,而在反拓扑序中C1是在C2前面的,此时说明G中第一遍DFS时先结束了C2,C1才结束的,假设C2中的点是从C1可达的,也就是 阅读全文
posted @ 2011-08-07 21:43 zqynux 阅读(675) 评论(0) 推荐(0) 编辑
摘要: tarjan基于这样一个定理:在任何深度优先搜索中,同一强连通支内的所有顶点均在同一棵深度优先树中。也就是说,强连通分量一定是有向图的某个深搜树子树。证明:在强连通支内的所有结点中,设r第一个被发现。因为r是第一个被发现,所以发现r时强连通支内的其他结点都为白色。在强连通支内从r到每一其他结点均有通路,因为这些通路都没有离开该强连通支(据引理1),所以其上所有结点均为白色(未染色,未访问)。因此根据白色路径定理,在深度优先树中,强连通支内的每一个结点都是结点r的后代。引理:白色路径定理:在一个有向或无向图G=(V,E)的深度优先森林中,结点v是结点u的后代当且仅当在搜索发现u的时刻d[u],从 阅读全文
posted @ 2011-08-07 21:27 zqynux 阅读(696) 评论(0) 推荐(0) 编辑
摘要: 终于琢磨出来了强联通分量,看了不少资料啊~~有三种算法,我用的第一种,最慢的,但是也是最普遍的。。 具体讲解看我转的一篇文章吧,代码如下:#include <stdio.h>#include <string.h>#include <stdlib.h>int num[200];int map[200][200];int count[200];int rmap[200][200];int rcount[200];int group[200];int order[200];int flag[200];int now;void srch1(int i){ int j 阅读全文
posted @ 2011-08-07 21:08 zqynux 阅读(191) 评论(0) 推荐(0) 编辑
摘要: 有向图的强连通分量『StronglyConnectedComponent』(SCC)一、Kosaraju算法1、伪代码Kosaraju_Algorithm:step1:对原图G进行深度优先遍历,记录每个节点的离开时间。step2:选择具有最晚离开时间的顶点,对反图GT进行遍历,删除能够遍历到的顶点,这些顶点构成一个强连通分量。step3:如果还有顶点没有删除,继续step2,否则算法结束。2、原理:说明:设F(u)为第一次调用DFS时计算出的完成时间。F(U)=max{F(u)},U为顶点集。定理:设C和C’为有向图G的两个不同的强联通分支。假设有一条边(u,v)属于E,其中u在C中,V在C’ 阅读全文
posted @ 2011-08-07 18:12 zqynux 阅读(529) 评论(0) 推荐(0) 编辑
摘要: 类似于二分的算法吧,看代码:#include <stdio.h>#include <stdlib.h>int pow_(int a, int b){ if(b == 0){ return 1; } if(b & 1){ return (pow_((a * a) % 1012, b / 2) * a) % 1012; }else{ return pow_((a * a) % 1012, b / 2) % 1012; }}int main(int argc, char **argv){ int n; int a, b; scanf("%d", & 阅读全文
posted @ 2011-08-07 17:35 zqynux 阅读(129) 评论(0) 推荐(0) 编辑
摘要: 暴搜就行,还有一个方法,是logn的算法的,等下看a^b2的代码吧,上暴搜的代码:#include <stdio.h>#include <stdlib.h>int main(int argc, char **argv){ int i; int a, b; int s = 1; scanf("%d%d", &a, &b); for(i = 1; i <= b; i++){ s *= a; s %= 1012; } printf("%d\n", s); return 0;} 阅读全文
posted @ 2011-08-07 17:34 zqynux 阅读(123) 评论(0) 推荐(0) 编辑
摘要: 果断直接SPFA,f[i][j]代表到达(i,j)的时间,f[i][j] = f[a][b] + num[i][j] (a, b) 是(i, j)相邻的.. 代码:#include <stdio.h>#include <stdlib.h>int map[25][25];#define MAX 4000struct box{ int x, y;}queue[MAX];int head, rear;int used[25][25];int dis[25][25];int m, n;void enqueue(int x, int y){ if(used[x][y]){ ret 阅读全文
posted @ 2011-08-07 17:33 zqynux 阅读(233) 评论(0) 推荐(0) 编辑
摘要: 我用的暴搜,别人说还有一种方法:题目要求n个数同余。等价于求这n个数两两求差(大减小)所得的所有数的最大公约数。 我的暴搜代码如下:#include <stdio.h>#include <stdlib.h>int num[100];int ans;int main(int argc, char **argv){ int i, j, t; int n, max = 0; scanf("%d", &n); for(i = 0; i < n; i++){ scanf("%d", &num[i]); if(max & 阅读全文
posted @ 2011-08-07 17:31 zqynux 阅读(227) 评论(0) 推荐(0) 编辑
摘要: 简单的模拟吧,大家都尝试尝试~~不太难,代码:#include <stdio.h>#include <ctype.h>#include <string.h>#include <stdlib.h>char str[101];char c;char *getval(char *str, int *i){ int t = 0, m = 0; if(str[0] == '-'){ m = 1; str++; }else if(str[0] == '+'){ str++; } while(isdigit(*str)){ t 阅读全文
posted @ 2011-08-07 10:46 zqynux 阅读(524) 评论(0) 推荐(0) 编辑