2011年10月30日
摘要: 虽然基本上和3352是一样的题意,但是要数据比较严格,这题有可能出现重边,而3352不会有重边。思路:直接在POJ3352,即上一篇博文上的代码稍微改动。新建一个char match[N][N],如果用int则内存超了。#include<iostream> #define min(a,b) (a<b?a:b) using namespace std; const int N=5005,M=10005; int n,m; char match[N][N]; struct Edge { int v,next; }edge[M]; int edgehead[N]; int k=1; 阅读全文
posted @ 2011-10-30 13:13 不是我干的 阅读(140) 评论(0) 推荐(0)
  2011年10月29日
摘要: 题意:给一个无向图,问你需要添加多少条边之后这个图变成双连通分量。关于桥和双连通分量之类的可以参看以下链接。http://www.byvoid.com/blog/biconnect/和http://blog.csdn.net/geniusluzh/article/details/6619575思路:/*一条无向边(u,v)是桥,当且仅当(u,v)为树枝边,且满足DFS(u)<Low(v)。*/#include<iostream>#define min(a,b) (a<b?a:b)using namespace std;const int N=1005,M=2005;in 阅读全文
posted @ 2011-10-29 11:23 不是我干的 阅读(229) 评论(0) 推荐(0)
  2011年10月26日
摘要: 题意:flymouse要去送礼物,送的每个人有一定的反馈comfort值,有正有负,给一个有向图,要你找出一条路径,沿着这个路径去送礼物可以使总的comfort值最大。注意题意里面的一个关键点:flymouse经过每个房间时,可以选择进去或者不进去,所以我们可以把负值的comfort值赋为0。思路:先用tarjan算法处理一遍强连通分量。然后缩点成有向无环图。然后简单dp:对有向无环图的每个节点进行有返回值的dfs,对树节点dfs递归时,比较子节点的返回值,取较大的作为返回值。思路正确但还是wa了很多次,原因出在dfs上,还是太菜了。#include<iostream> #defi 阅读全文
posted @ 2011-10-26 20:42 不是我干的 阅读(411) 评论(0) 推荐(0)
  2011年10月25日
摘要: 题意:就是判断一个图是否为弱连通图。思路:先用tarjan处理一遍找出强连通分量。然后将每个强连通分量缩点,形成一个有向无环图。如果该有向无环图是一个无分叉的树的话,即是弱连通图。如果有分叉,则分叉两端的节点无法互相到达,即不是弱连通图。#include<iostream> #define min(a,b) (a<b?a:b) using namespace std; const int N=1005,M=6005; int n,m; int edgehead[N]; struct Edge { int v,next; }edge[M]; int indegree[N]; i 阅读全文
posted @ 2011-10-25 19:20 不是我干的 阅读(231) 评论(0) 推荐(0)
  2011年10月24日
摘要: 我是从算法导论看起的:定义:在一个有向图中,任意两个点都是互相可达的,则称为强连通图。解法步骤:1.先对每个节点dfs。计算出 每个节点的finishing time f[u]。2.对图进行倒置处理。3.对倒置图的每个节点,按照f【u】降序的顺序进行dfs。4.输出在步骤3中dfs时建立的每棵树的节点。这些树即分别是强连通分支。时间复杂度分析:在给定图G的邻接表表示的情况下,建立G倒置图的时间复杂度为O(V+E)。而dfs也是O(V+E),故整个时间复杂度是线性时间O(v+e).对这个解法的理解关键在理解finishing time的特点,算法导论书上对其有关键推论。根据上面算法写的粗糙代码: 阅读全文
posted @ 2011-10-24 23:02 不是我干的 阅读(841) 评论(0) 推荐(0)
  2011年10月21日
摘要: 题目大意:给一些单词,如果某个单词的首字母和另一个单词的尾字母相同,则两个单词可以连接起来。要求判断能否把全部单词连接起来。思路:欧拉通路。先构图:每个字母为点。然后对每个单词,将单词的首字母和尾字母连一个单向边。#include<iostream> using namespace std; const int N=100005; char str[1005]; int n; struct Edge { int v,next; }edge[N]; int edgehead[30]; int k=1; int in[30]; int out[30]; bool start[30]; 阅读全文
posted @ 2011-10-21 18:28 不是我干的 阅读(193) 评论(0) 推荐(0)
  2011年10月20日
摘要: 思路:很显然是一个欧拉无向图。因为要遍历每个边两遍而且方向不同。所以可以看成是有向图来处理。以下代码是 dfs+邻接表。这里注意的dfs和普通的dfs不一样在于终止条件。以前的dfs都是找到某个点后终止,现在是直到遇到某个点,那个点已经无路可走了,再终止。(因为题目已经保证要求的路径存在)还有就是有些人估计疑惑为什么没用到栈来输出。其实不用栈的原因很简单,就是欧拉回路的路径是对称。起点终点都是1,你从终点走过来和从起点走过来都是符合题意。第一次接触欧拉图,还有这题算简单的,一次AC水过。#include<iostream> using namespace std; const in 阅读全文
posted @ 2011-10-20 13:55 不是我干的 阅读(506) 评论(0) 推荐(0)
  2011年10月10日
摘要: 题目:给定人名和群组的关系,叫你把每个人分配到某个群组的关系,使这个分配方案满足最大的那个群组人数 最小。思路:二分图匹配。求法是用二分答案加最大流判定。#include<iostream> using namespace std; #define MIN(a,b) (a<b?a:b) const int N=1505,M=1100005; const int inf=(1<<29); char name[20]; int n,m; struct Edge { int v,next,w,re; }edge[M]; int edgehead[N]; int k=1; 阅读全文
posted @ 2011-10-10 21:45 不是我干的 阅读(168) 评论(0) 推荐(0)
摘要: 题意很简单:就是给你一个矩阵,给定矩阵行的和 and 矩阵列的和。然后矩阵内每个数会受到一定约束。要你填好这个矩阵的每个数,满足约束的轻快下,让每行数的和and每列数的和满足题意。思路很简单:只要想到是用流网络即可。每个行i是一个点,每个列j是一个点。自己设定出源点s(一般为0)和汇点t(一般为n+m+1),每个行sum是源点到这个行i的边容量,每个列sum是列j到汇点的容量。然后将行i到列j的边容量先都初始化为inf。然后就是转化每个约束条件.非常恶心。下面这个链接是一哥们的,里面还有他找的testdata。http://hi.baidu.com/forsona/blog/item/662c 阅读全文
posted @ 2011-10-10 14:18 不是我干的 阅读(121) 评论(0) 推荐(0)
  2011年10月8日
摘要: 顾名思义。点连通度即使在一个图中,去掉多少个点可以使这个图不连通。因为点连通度的求法是构图时转化为边连通度来求的。而边连通度的求法:构造一个流网络,每个无向边的容量为1。任意取一个点作为源点。枚举剩下的店作为汇点,求最小割。枚举完取最小割最小的值就是ans。(我的理解其实就是整体的边连通度是取决于“最短板”,即存在的两个点间连通强度最弱。)(而刚好最小割其实就是流网络流求最大流时的“最短板”,故此时边连通度突然和最小割连通起来也不是那么不可思议了吧)构图:(拆点)(1)原G图中的每个顶点v变成N网中的两个顶点v'和v",顶点v'至v"有一条弧(有向边)连接, 阅读全文
posted @ 2011-10-08 21:00 不是我干的 阅读(267) 评论(0) 推荐(0)