08 2012 档案

摘要:题意:给图按黑白着色,求一种着色方案使得图中着黑色的顶点数最多且这些顶点相互之间都不相邻.分析: 求出补图的最大团即为答案。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))#define maxn 111int g[maxn][maxn];int res[maxn];int s[maxn];int sum;int n,m,sn,ans;void dfs(int r){ int i,j; if(r>n) { for(i=1;i<=n;i++) res[... 阅读全文
posted @ 2012-08-30 23:43 'wind 阅读(224) 评论(0) 推荐(0)
摘要:题意: 已知一个有 n 个点的五向图,有重边,找出找出一个边集,使得这些边去掉之后原图不连通,并且去掉的边的数目要尽可能的少。分析: 求最小割边集用o(n^3)的stoer-Wagner算法,用最大流会TLE。 算法详解 http://blog.sina.com.cn/s/blog_700906660100v7vb.html#include<cstdio>#include<cstring>#define INF 0x1f1f1f1f#define clr(x)memset(x,0,sizeof(x))#define min(a,b)(a)<(b)?(a):(b)# 阅读全文
posted @ 2012-08-30 13:41 'wind 阅读(1034) 评论(0) 推荐(0)
摘要:题意: 有一个有n个点的无向图,已知 m 条边,每条边有权值和一个字母标号,字母标号有四种 'L' 'O' 'V' 'E' 要找一条从1点到n点去的一条路径,然后要求有LOVE的的条件下路径最短,如果有多条最短路,找LOVE最多的那条分析: 将每个点分为四个,代表L,LO,LOV, LOVE四种状态#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))const long long inf=1ll<<57;co 阅读全文
posted @ 2012-08-30 00:23 'wind 阅读(245) 评论(0) 推荐(0)
摘要:题意: 现有一个空的集合,有连续的 m 组操作 B x 将 x加入集合 A x 询问集合中的元素 y % x 的取得最小值的 y分析:鸽巢定理+线段树然后对每个y,由鸽巢定理,连续的y+1个数中必然存在mod y相同的数,可以多区间查询, 即[0, y - 1] [y , 2 * y - 1] 取最优解当y比较小的时候,直接遍历会更快,即当 y<log(n) 的时候采用遍历的方法 由于数据比较少,可以先进行离散化来提高效率。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))# 阅读全文
posted @ 2012-08-29 16:49 'wind 阅读(252) 评论(0) 推荐(0)
摘要:题意:有一个长度为 N 的墙,定义两种操作: 1 a b c 将 区间[a,b]涂成 c颜色 2 a b c 询问区间[a,b]中c颜色的的个数。分析 : 区间合并类线段树。#include<cstdio>#include<cstring>#define clr(x)memset(x,0,sizeof(x))#define maxn 100005#define max(a,b)(a)>(b)?(a):(b)#define min(a,b)(a)<(b)?(a):(b)int hi[maxn<<2];int lo[maxn<<2];in 阅读全文
posted @ 2012-08-27 21:44 'wind 阅读(241) 评论(0) 推荐(0)
摘要:题意: 有n个人进行一场自行车竞速比赛,知道了每个人第1s走fi米,以后每秒走si米,一个人扔钉子破坏比赛,每秒他都选最靠前的那个人,如果有多个人,选编号最小 的那个,问你这些人依次被破退出比赛的顺序。分析: Si最大只有100,可以建立优先队列数组s[1..100],对于每个优先队列,按第一关键字Fi第二关键字ID排序,每次取出所有的优先队列里最大值,然后直接 计算(Time-1)*Si + Fi 找最大的way,将对应的优先队列pop并输出对应ID即可。#include<cstdio>#include<cstring>#include<queue>#in 阅读全文
posted @ 2012-08-27 20:28 'wind 阅读(322) 评论(0) 推荐(0)
摘要:题意: 有N 个人,知道了每个人知道的信息,和它最多能告诉别人的信息数目,问编号为 m 的人最多能知道的信息条数是多少。分析: 由于信息的编号比较大,所以先需要进行离散化。 每个人和自己知道的每个信息之间都有一条边相连, 每个人匹配容量为 他最多能告诉别人的信息数目。#include<stdio.h>#include<string.h>#define maxn 222#define clr(x)memset(x,0,sizeof(x))int cap[maxn]; int map[maxn][maxn];int vlink[maxn]; ... 阅读全文
posted @ 2012-08-26 19:45 'wind 阅读(350) 评论(0) 推荐(0)
摘要:题意: 给出一个序列和 M 个询问,对于每个询问输出询问区间内从右向左第一个出现次数超过 2 的数。分析:预处理用 before[i] 表示第 i 个数之前出现的距离第 i 个数最近求和 第 i 数相等的数的值。 区间查询的时候先查询右儿子区间,再查询能合并的区间,再查询左儿子区间。#include<stdio.h>#include<string.h>#include<map>using namespace std;#define maxn 500005#define max(a,b)(a)>(b)?(a):(b)int va[maxn];int be 阅读全文
posted @ 2012-08-26 19:40 'wind 阅读(289) 评论(2) 推荐(0)
摘要:题意: 给出一个地图,要求找出至少经过K条边的最短路,可以走重边。分析:二维最短路,用dis[i][j] 记录 在i 点进过j 条路的最短路 找到dis[i][k]的最小值。SPFA:#include<stdio.h>#include<string.h>#include<queue>#define INF 0x1f1f1f1fusing namespace std;#define maxn 5005struct node{ int to,next,w;}e[200005];int tot;int head[maxn];void add(int s,int u 阅读全文
posted @ 2012-08-26 11:13 'wind 阅读(223) 评论(0) 推荐(0)
摘要:题意: 给N个人依次分卡片,然后从的第一个人到最后一个人依次拿走全部的卡片,问最少经过多少次,可以使得卡片回复到原来的次数。分析:求出每个卡片循环到原来位置的最少次数,在一个循环节中,每个卡片的循环次数相同,求出这些循环次数的最小公倍数即可,(输入要用%I64d,用%lld wa了好长时间)#include<stdio.h>#include<string.h>#define maxn 1000long long next[maxn];long long a[maxn];long long gcd(long long x, long long y){ if(!x||!y) 阅读全文
posted @ 2012-08-25 21:58 'wind 阅读(247) 评论(0) 推荐(0)
摘要:题意: 给出一个有N 个节点,和M 条边,这些边分为 蓝色和红色的,问是否存在一种情况为 恰好用 k个蓝色的边,和已有的若干条红色边,将原图连成一棵树。分析: 两次 Kruskal ,第一次的时候先把能用的红色边全部用上,然后用蓝色边,这些用到的蓝色边都是最终的生成树所必需的,将其标记如果发现需要的蓝色边数目大于 K,或用完了能用的蓝色边之后图还未连通,则不存在符合条件的情况 第二次Kruskal的时候,先把之前标记的蓝色边全部用上,然后在剩下的蓝色边选出能用的边,如果总数能达到K则存在符合的情况。#include<stdio.h>#include<string.h># 阅读全文
posted @ 2012-08-25 19:41 'wind 阅读(303) 评论(0) 推荐(0)
摘要:题意: 知道了汉诺塔的一个状态,求把全部汉诺塔移动到B上的步数。分析: 逆向推即可。#include<stdio.h>#include<string.h>char str[100] ;long long calc(char A, char B, char C, int n){ if(n==0) return 0 ; if(str[n-1]==B) return calc(C,B,A,n-1) ; if(str[n-1]==A) return calc(A,C,B,n-1)+(1LL<<(n-1));}int main (){ ... 阅读全文
posted @ 2012-08-25 19:26 'wind 阅读(199) 评论(0) 推荐(0)
摘要:题意: M2%10x=N ,给出n值,找到满足等式的最小m值,x=(0,1,2...)。分析: 由于M的位数不可能超过n的位数,可以从n的最后一位开始逐位搜索。#include<stdio.h>#include<string.h>const __int64 INF=999999999;__int64 num[25];__int64 min(__int64 a,__int64 b){ return a<b?a:b;}__int64 ans,n;int top;__int64 p;void dfs(int pos,__int64 w,__int64 res){ if( 阅读全文
posted @ 2012-08-25 10:54 'wind 阅读(286) 评论(0) 推荐(0)
摘要:题意: 给两个数组,求最长公共递增子序列。分析: dp[i,j]表示a串前i个字符,b串前j个字符组成的,并且以b[j]为结尾的最长的LCIS,转移方程: dp[i,j]=dp[i-1,j]; //a[i]与b[j]不等 dp[i,j]=dp[i-1,k]+1; (1<=k<=j-1) //a[i]与b[j] 相等 以上转移方程是O(n^3)时间复杂度 优化: 由于最外层循环是 i,第二层是 j,循环 j 的时候,实际上同时找出dp[i-1,k] 的最大值MAX 方法:循环 j 的同时,若a[i]>b[j],更新MAX (因为当且仅当a[i]>b[j]时,后边循环 j 阅读全文
posted @ 2012-08-25 09:06 'wind 阅读(1378) 评论(0) 推荐(0)
摘要:题意: 有N件商品,知道了商品的价值和销售的最后期限,只要在最后日期之前销售处,就能得到相应的利润,并且销售该商品需要1天时间,求出最大利润。分析:利用并查集按利润排序,建立一个关于时间的并查集 每次插入一个物品时,若该物品时间为 i,找出find(i),记为t,若t不为0,则将该物品安排到t这个时间完成,并使f[t]=t-1 亦即对于每个物品尽量 安排在后边完成,安排后将fa指针前移,表示这个时间已经被占用,下次需要插入到它之前。#include<stdio.h>#include<string.h>#include<algorithm>#define cl 阅读全文
posted @ 2012-08-25 00:02 'wind 阅读(829) 评论(0) 推荐(0)
摘要:题意: 给出有n 个节点的网络,和m条单向边,知道了每条边的容量,问哪些边满足增加该边的容量后,能使得从起点到终点的总流量增加(只能修改一条边!)。分析:如果某条边是该关键边,首先满足该边一定能满流,其次要有从 s 到 t 经过该边的可行路径。 先求最大流,找出割边,在正向网络上从 s 开始深搜,将遍历到点用v1[]标记,在反向网络上从 t 深搜,将遍历到的点用v2[]标记, 如果某条边满足 e[i].cap=e[i].flow且v1[e[i].from]=1,e[e[i].to]=1,那么该边即为要求的关键边。#include<stdio.h>#include<string 阅读全文
posted @ 2012-08-24 23:10 'wind 阅读(203) 评论(0) 推荐(0)
摘要:题意: 有 n 个人,他们之间的关系有四种,给出一些关系 a,b 表示b 知道 a,现在想把这些人分成两组,每个组里面所有人都相互知道,如果可以分成这两组, 找出两组人数相差最少的情况。分析:如果 a 和 b 不是相互知道,就在a,b之间连一条双向边,表示a 和b 绝不能分在一个组里 建好图之后,进行染色,判断是否是二分图,如果不是二分图,肯定不存在符合条件的情况 染色的同时,记录每个连通块中每个部分的个数,并记录路径 用 01 背包标记所有存在的状态,找到差值最小的情况#include<stdio.h>#include<string.h>#define clr(x)m 阅读全文
posted @ 2012-08-24 19:56 'wind 阅读(1221) 评论(0) 推荐(1)
摘要:题意: 给出n 个数,每个数的范围在1..k之间,问最短非子序列的长度是多少。分析:将集合尽可能划分成多个区间,并满足每个区间包含1..k之间所有的数,如果分成了 x 个区间,那么这些区间一定包含了所有长度为 x 的子序列,而没有包含全 部的长度为 x+1 的子序列,因为可以通过在每个区间任取一个数来组成长度为 x 的序列。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))int v[10005];int main(){ int n,k,p,i,res,num; while(sca 阅读全文
posted @ 2012-08-24 12:39 'wind 阅读(980) 评论(0) 推荐(0)
摘要:题意: 一群伞兵要降落在一个m*n的区域,知道了每个伞兵落入的位置,防守方可以在任意一排或任意一列安装武器,分别可以防御某一排或某一列的敌人,知道了武器放 某一排或某一列的建造费用,找出一种建造方案使得所有武器花费的乘以最小并足以防御任意一个位置的敌人。分析:建图方式:将每一行看成一个点(1..n),将每一列看成一个点(n..n+m)建立一个源点 s = 0, 汇点 t = n+m+1 在 s 和每个行顶点之间连一条容量为行造价的边 在每个列顶点和 t 之间连一条容量为列造价的边 如果(x,y)位置有伞兵,就在 x 行和y列之间连一条容量为无穷大的边 求出最小割即为最小费用,需要注意的地方是要 阅读全文
posted @ 2012-08-23 23:35 'wind 阅读(202) 评论(0) 推荐(0)
摘要:题意: 给出一个 n*m的矩阵,知道了每一行元素的和(n个),每一列元素的和(m个) 给出t个条件: a b c d 表示 a b 和 数字 d 满足条件 c分析: 此题的最大流有下界的限制,用上下界最大流求解时,需要先去掉下界,判断是否存在可行流将 1 到 n 行每行看作一个节点(1..n),将 1 到 m 列每列看作一个节点(n+1..n+m) 建立源点 s=0,汇点 t=n+m+1 在源点 s 和每一个行节点之间连一条上界是行数字的和下界为 0的边在每一个列节点和和汇点t之间连一条上界是列数字的和下界为 0的边 如果 i 行 j 列的数字大于 x,就在 i 行节点和 j 列节点之间... 阅读全文
posted @ 2012-08-22 19:28 'wind 阅读(327) 评论(0) 推荐(0)
摘要:题意:给定带点权的有向无环图,求最大权闭合图权值,同时要使得选取的点数最小分析:建图: 建立源点 s=0,在 s 和 正权点之间连一条边权为该点值的边 建立汇点 t=n+1 在 负权点 和 t 之间连一条边权点为该点的绝对值的边 输入的边权值设为INF,求最大流,求最大流后,在残留网络中从s出发dfs能搜到点都为最大权闭合图中的点, 即这个最小割对应的是最大权闭合图然后让正权点值的累加和减去最大流 就是闭合图的最大权。#include<stdio.h>#include<string.h>#include<stdlib.h>#define clr(x)mems 阅读全文
posted @ 2012-08-21 00:22 'wind 阅读(216) 评论(0) 推荐(0)
摘要:题意: 对于从1到N (1 <= N <= 39) 的连续整数集合,能划分成两个子集合,且保证每个集合的数字和是相等的。举个例子,如果N=3, 对于{1,2,3}能划分成两个子集合,每个子集合的所有数字和是相等的:{3} 和 {1,2} 给出一个 N 值,问最多能划分成多少种等值的集合。分析:每个数字只用到一次,每种情况的存在数可以由之前的存在的数来递推得到,01背包的变形。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))long long f[50000];int 阅读全文
posted @ 2012-08-20 21:17 'wind 阅读(970) 评论(3) 推荐(0)
摘要:题意: 给出一连串的表达式,需要求出他们的结果,并且需要判断这些结果能否首尾相连成一个串,如果可以输出字典最小的那个串。分析:表达式求解需要定义符号的优先级,并用栈来维护运算符和数值结果, 结果求出来后,可以对所有串按字典序排列,然后深搜找欧拉路径,第一次找到的即为字典序最小的那个。#include<stdio.h>#include<string.h>#include<stdlib.h>#define clr(x)memset(x,0,sizeof(x))int res[1005][3];struct node{ int f,l; char s[33];}q 阅读全文
posted @ 2012-08-19 22:19 'wind 阅读(235) 评论(0) 推荐(0)
摘要:题意: 知道了一些课程的开始和结束时间,要从中选择尽量多的课程,而且每五分钟只能选一次。分析: 因为每五分钟最多选一次,所以只要枚举总的开始时间,以后的时间就可以确定,总的开始时间最多为 4 种情况,找到其中的最大值即可。#include<stdio.h>#include<string.h>#include<stdlib.h>#define clr(x)memset(x,0,sizeof(x))struct node{ int st,en;}q[555];int v[555];int cmp(const void*p1,const void*p2){ nod 阅读全文
posted @ 2012-08-19 22:13 'wind 阅读(230) 评论(0) 推荐(0)
摘要:题意:为了降低出现暴动及逃跑事件的风险,两个相同容量的临近监狱的管理层决定重新安排他们的囚犯。他们想用一个监狱里一半的囚犯去交换另一个监狱里一半的囚犯 然而,从囚犯们犯罪史的存档信息可知某些囚犯成对被关在同一座监狱里时会很危险,这也是现今他们被分开的原因,即对于每对这样的囚犯,一名在第一个监狱服 刑,另一名在第二座监狱服刑。管理层认同将那些囚犯保持分开的重要性,但这也使得他们的新安排任务有些棘手,事实上,他们很快就了解到有时这个互换一半囚 犯的意愿是不可能达成的。每当这种情况下,他们不得不满足于交换尽可能接近一半数量的囚犯。分析:需要把第一座监狱和第二所监狱有联系的放到一起,形成一个连通块,即 阅读全文
posted @ 2012-08-19 21:59 'wind 阅读(294) 评论(0) 推荐(0)
摘要:题意:恐怖分子在去年轰炸哈理工未遂后,打算今年卷土重来,学校为了预防恐怖分子潜入主楼,决定在今年9月份在每间教室安装摄像头,恐怖分子为了能够成 功潜入主楼,将要摧毁这些摄像头。 已知摄像头的安装是成网络状的,摄像头的连接是双向的。如果网络中任何两个摄像头之间至少有一条路,则该网络为连通的,否则不连通。一个空的网络 或只有一个摄像头的网络被认为是连通的。如果网络不连通,则导致摄像头主系统瘫痪,恐怖分子会成功潜入主楼。因为摄像头之间的连线是接在墙里的, 所以只能靠摧毁摄像头使网络不连通,做为恐怖分子头目的你,请你计算至少要摧毁多少个摄像头才能让你的手下成功潜入主楼。分析:使得网络不连通所需去除的最 阅读全文
posted @ 2012-08-19 21:52 'wind 阅读(320) 评论(0) 推荐(0)
摘要:题意:Colugu市有n个车站和m条路。每条路直接连接两个车站,所有的路都是单向的。为了维护空气质量,政府停用了所有军队车辆。所以军队必须乘坐巴士去机场。两个车站之 间可能不只一条路。如果一个车站被摧毁,那么所有通向那个车站的道路都没用了。Gabiluso需要去做的是摧毁一些车站使得军队不能在k分钟内 赶到机场。一辆巴士通过一条路只需要一分钟。从1到n给所有车站编号。编号为1的车站在军营里,编号为n的车站在机场里。军队总是从编号为1的车站出发 由于有重兵把守,所以编号为1和n的车站不能被摧毁。当然那里没有一条路直接从1号车站连接到n号车站,请帮助Gabiluso计算他需要摧毁车站的最小数量,他 阅读全文
posted @ 2012-08-19 21:44 'wind 阅读(308) 评论(0) 推荐(0)
摘要:题意: 求多边形重心。分析: 直接利用公式。#include<stdio.h>#include<string.h>#include<math.h>struct node{ double x,y;}q[1000005],cen;double mul(node a,node b,node c){ return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x);}int main(){ double s,a; int t,n,i; scanf("%d",&t); while(t--) { scanf(&qu 阅读全文
posted @ 2012-08-17 12:52 'wind 阅读(213) 评论(0) 推荐(0)
摘要:题意: 给出一个有N个顶点的多边形,问该多边形内是否存在一点满足在该点可以看到多边形内部任意一个位置。分析: 求多边形内核。#include<stdio.h>#include<string.h>#include<math.h>#define eps 1e-8#define maxn 105struct point{ double x,y;}p[maxn],q[maxn],s[maxn];int n,size,si;void init(){ int i; for(i=1;i<=n;i++) p[i]=s[i]; p[n+1]=p[1]; p[0]=p[. 阅读全文
posted @ 2012-08-16 21:56 'wind 阅读(266) 评论(0) 推荐(0)
摘要:题意:有 N 个奶牛,奶牛A可能认为B 优秀,奶牛B可能认为C优秀,这种关系具有单向传递性,即在此情况下,奶牛A认为奶牛C也是优秀的,但奶牛B不一定认为A优秀, 问可以找出有多少个奶牛可以被其他所有奶牛都认为是优秀的。分析:如果奶牛A认为奶牛B优秀,就连一条从B到A的边,求出强连通分量并染色缩点,最后计算入度为0 的强连通分量是否只有一个,如果是则输出该强连通分量内点的 个数,否则就不存在满足条件的奶牛。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))#define min(a, 阅读全文
posted @ 2012-08-16 21:52 'wind 阅读(214) 评论(0) 推荐(0)
摘要:题意: 给出一个有N个节点的无向图和 M 条边,每条边都有一个重力承受度,要从中找出一条从 1 节点到 n节点的路径,使得可以经过的车辆载重最大。分析:类似于最大流中找增广路,在求最短路的松弛操作上加以修改。SPFA:View Code #include<stdio.h>#include<string.h>#define min(a,b)(a)<(b)?(a):(b)#define clr(x)memset(x,0,sizeof(x))#define INF 0x1f1f1f1fstruct node{ int to,next,w;}e[1000005];int 阅读全文
posted @ 2012-08-16 16:02 'wind 阅读(181) 评论(0) 推荐(0)
摘要:题意: 国王有 N 个王子,一共有 N个女子,知道了每个王子喜欢的女子,和一组互不冲突的男女匹配,问每个王子可以娶那些女子且不影响其他所有的王子都可以娶到 自己喜欢的女子。分析: 如果某个王子喜欢某个女子,就连一条从该王子到该女子的边,如果某个女子某个王子可以匹配,就连一条从该女子到该王子的边。 如果一些王子和一些女子的同一个强连通分量里,则这些王子可以娶该强连通分量里的任意的女子。#include<stdio.h>#include<algorithm>#include<string.h>using namespace std;#define maxn 40 阅读全文
posted @ 2012-08-16 10:02 'wind 阅读(160) 评论(0) 推荐(0)
摘要:题意: 知道了N 个学校,以及每个学校提供软件支持的学校编号,一个学校得到软件支持之后便可以支持他能支持的学校,问至少对多少学校提供软件支持可以使得 所有学校都得到软件支持,和至少在这些学校添加多少条边能使得任何一个学校得到软件支持后,其他所有学校都能得到软件支持。分析: 先求出所有的强连通分量并进行染色缩点,找出入度为 0 的强连通分量,其个数即为使所有学校得到支持所需要提供软件支持的最小数量, 而根节点与叶子节点 数量中的最大值即为最少添加的边数。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0, 阅读全文
posted @ 2012-08-15 22:35 'wind 阅读(214) 评论(0) 推荐(0)
摘要:题意: 有 N个村庄,和 M 个区域,M个区域是由N个村庄之间的围墙分割而成,如:图中10个村庄间的围墙把地形分成了10 个区域,知道了一些人的所在的村庄的位置,想找一个区域,使得这些人到达这个区域经过的围墙数总和最小,并求出最小值。分析: 要把各个区域看成点,两两区域间的围墙看成边来建图,如果两块区域之间有围墙相隔,那么就在这两个区域之间建一条长度为1 的边, 图建完之后用 FLOYED 求出两两点的最短距离, 计算每个人到达某个区域的最小距离时,要枚举和该人所在村庄相邻的区域。 依次枚举目标区域找出最小值。#include<stdio.h>#include<string. 阅读全文
posted @ 2012-08-15 21:19 'wind 阅读(246) 评论(0) 推荐(0)
摘要:题意:有 M 个猪圈,每个猪圈里初始时有若干头猪,一开始所有猪圈都是关闭的,依次来了 N 个顾客,每个顾客分别会打开指定的几个猪圈,从中买若干头猪, 每个顾客分别都有他能够买的数量的上限,每个顾客走后,他打开的那些猪圈中的猪,都可以被任意地调换到其它开着的猪圈里,然后所有猪圈重新关上。分析:此题建图关键在于合并猪圈 建图: 对于每个猪圈的第一个顾客,从源点向他连一条边,容量就是该猪圈里的猪的初始数量 如果从源点到一名顾客有多条边,则可以把它们合并成一条,容量相加, 对于每个猪圈,假设有 n 个顾客打开过它,则对所有整数 i ∈ [1, n),从该猪圈的第 i 个顾客向第 i + 1 个顾客连一 阅读全文
posted @ 2012-08-15 13:34 'wind 阅读(242) 评论(0) 推荐(0)
摘要:题意: 给出一定的大写字母,并依次给出 m 个两两关系,如果在输入关系的过程中发现有环,或已经能确定所有序列的关系,则输出相应的结果,并且以后输入的关系 不会对当前结果产生影响。分析: 如果在输入过程每输入一个进行依次拓扑排序,如果排序中出现没有 0 入度的点则说明有环,如果每次找到的 入度为 0 的点均为一个,并且找到n 个,则顺序 可以被确定。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))int g[30][30];int d[30];int res[30];int n;i 阅读全文
posted @ 2012-08-15 09:22 'wind 阅读(162) 评论(0) 推荐(0)
摘要:题意: 已知有 N 个牛棚,且每个牛棚在一开始的时候有一定数量的牛,每个牛棚可以用来让牛避雨,但容量都有一定的限制,知道了一些牛棚之间的道路长度,问使得下雨时使所有牛都可以找到地方躲雨,且要使得所有牛中走过的路中的最大值尽可能小,并求出该最大值分析: 建图:将每个牛棚拆成两个点v,v` 建立一个源点 s =0 , 在 s 和每个点 i 之间连一条容量大小为该牛棚初始牛数量的边, 建立一个汇点 t =2*n+1 在 每个点 i+n 和 t 之间连一条容量大小为该牛棚容量的边。 如果点 u 和 v 满足条件,就在 u 和 v +n ,v 和 u+n之间连一条容量大小为 INF 的边。 如果最大流 阅读全文
posted @ 2012-08-14 17:10 'wind 阅读(223) 评论(0) 推荐(0)
摘要:题意: 一个三层书架,现要把一些高度和厚度不等的书放进书架,每层至少放一本,问书架面积最少是多少,且要保证书架是矩形的。 分析: 先对书按从高到低排序,不妨把最高的一本书放在第一层,这样第一层的高度就不用考虑了 dp[i][j] 表示第二层厚度为 i ,第三层厚度为 j 时第二和第三层书架高度和的最小值#include<stdio.h>#include<string.h>#include<stdlib.h>#include<algorithm>#define INF 601using namespace std;struct node{ int 阅读全文
posted @ 2012-08-14 14:41 'wind 阅读(241) 评论(0) 推荐(0)
摘要:题意: 给出一个A~Z的置换,问是否可以被表示为一个置换的平方(即G=G'*G')结论: 通过观察可以发现: 一个置换乘上它本身,其中长度为偶数的循环节必然会分裂为两个长度相等的循环节,长度为奇数的循环节还是一个循环节,长度不变 ○ 置换中长度为偶数的循环节必然是原置换中的循环节分裂出来的○ 长度为奇数的循环节有可能是原置换中的循环节分裂出来的 因为只要判断能否被表示,所以可以忽略长度为奇数的循环节,只对长度为偶数的循环节进行考虑即可。 因为一个长度为偶数的循环节分裂出来的两个循环节的长度相等且同为原循环节长度的一半, 所以,只要给出置换中所包含的长度为偶数的循环节能一一配对, 阅读全文
posted @ 2012-08-14 11:24 'wind 阅读(207) 评论(0) 推荐(0)
摘要:题意: 知道了一个序列a[1]..a[n] ,给出 m 个约束条件,① st sn gt ki 表示a[st]+a[st+1]+..a[st+sn]>ki ② st snlt ki表示a[st]+a[st+1]+..a[st+sn]<ki 问是否存在这样的 a[i] 序列。分析: 将上面的两个不等式等价转换建立差分约束系统 将 ① 变为s[st-1]-s[st+en] < -ki <=-ki-1 将 ② 变为s[st+en]-s[st-1] < ki <=ki-1 求解这个差分约束系统,看最后有无冲突// gt dis[s[i].en]-dis[s[i].s 阅读全文
posted @ 2012-08-14 10:26 'wind 阅读(227) 评论(0) 推荐(0)
摘要:题意: 知道了数轴上的n个区间,每个区间都是连续的int区间,现在要在数轴上任意取一堆元素,构成一个元素集合V要求每个区间和元素集合V的交集至少有两个不同的元素 求集合V最小的元素个数。转一分析:(差分约束)设s[x] = 从0 到x 的所有在集合中的数的个数则ai到bi的个数即S[bi] - S[ai-1]。因此有(1) S[bi] - S[ai-1] >= 2。又根据s[x]本身的性质,后面的一定不比前面的小,后面的最多比前面多一,有:(2) s[i + 1] - s[i] >= 0 (3) s[i + 1] - s[i] <= 1故建图,使图中每一组边,均满足(注意三条 阅读全文
posted @ 2012-08-13 23:01 'wind 阅读(191) 评论(0) 推荐(0)
摘要:题意: 给出一个 n*n的数字矩阵,从左上角走到右下角每次只能向下或向右走,且每个格子中的数字只能取一次,问走k次之后可以取到的最大的数值和为多少。分析: 比较经典的网络流解DP的题目,可以用费用流求解, 建图: 将每个割格点拆分成两个点 v(入点),v`(出点),在v 和v`之间先连一条容量为 1 ,费用为格子数值的边,再连一条容量为无穷大费用为0的边, 这样既可以保证每个数只被取一次,又能保证可以多次经过这个数所在的格子 建立源点 s = 0,在 s 和 最左上角的格子的入点之间连一条容量为 K,费用为0 的边 建立汇点 t = n*n*2+1,在 t 和最右下角的格子的出点之间连一条容量 阅读全文
posted @ 2012-08-13 15:13 'wind 阅读(282) 评论(0) 推荐(0)
摘要:题意: 已知有n个插头,知道了m个用电器和其能插的插座型号,和k个转换器,问最少有多少个用电器无法连接到相应的插座上。适配器的作用: 例如:有插座C 转换器B(插孔) C(插头) 如果用电器能插到插座B上,那么通过转换器,它就能插到C上。分析: 建图的时候递归建图,如果用电器能直接连到某个插座或通过转换器间接查到某个插座上,就在期间连一条边,求出最大匹配,用总数减去即为剩下的无法连接个数的最小值#include<cstdio>#include<cstring>#include<string>#include<map>#include<ios 阅读全文
posted @ 2012-08-13 11:57 'wind 阅读(365) 评论(0) 推荐(0)
摘要:题意: 年轻的探险家来到了一个印第安部落里。在那里他和酋长的女儿相爱了,于是便向酋长去求亲。酋长要他用10000个金币作为聘礼才答应把女儿嫁给他。探险家拿不出这么多金币,便请求酋长降低要求。酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币。如果你能够弄来他的水晶球,那么只要5000金币就行了。"探险家就跑到大祭司那里,向他要求皮袄或水晶球,大祭司要他用金币来换,或者替他弄来其他的东西,他可以降低价格。探险家于是又跑到其他地方,其他人也提出了类似的要求,或者直接用金币换,或者找到其他东西就可以降低价格。不过探险家没必要用多样东西去换一样东西,因为不会得到更 阅读全文
posted @ 2012-08-13 09:06 'wind 阅读(203) 评论(0) 推荐(0)
摘要:题意: 知道了一些出租车任务的时间,每个任务需要一辆出租车从该任务的起点到终点,有些任务有时间上的冲突,问最少需要多少 辆出租车能完成任务。分析: 最小路径覆盖。 如果两个任务没有冲突,就在两个任务之间连一条边,找出最少的路径条数来覆盖所有点,(一条路径只需要一辆车)。 最小路径覆盖 = 总权 - 最大匹配#include<stdio.h>#include<string.h>struct node{ int to,next;}e[1000000];int tot;int head[505];void add(int s,int u){ e[tot].to=u; e[to 阅读全文
posted @ 2012-08-12 23:19 'wind 阅读(200) 评论(0) 推荐(0)
摘要:题意: 已知一个有 N 个节点 M 条边的无向图,问最短路和比最短路长度大1 的次短路共有多少条。分析: 在原来的dijkstra()上加一点变动,d[i][0]记录最短路的长度,d[i][1]记录次短路的长度,dp[i][0] 到达当前点最短路的条数,dp[i][1]到达当前点次短路的条数。View Code /************************************************************************************ 采用dijstra算法的思想,每次从dis[N][2]中选择一个未被标记且值最小的点dis[v][p] (可能.. 阅读全文
posted @ 2012-08-12 10:50 'wind 阅读(221) 评论(0) 推荐(0)
摘要:题意: 有一个有 N 个节点M 条边的的有向图,每个点对应两种操作: 将该点所有入边删除 ‘+’ ,对应一个花费,将该点所有出边删除 ‘ - ’亦对应一个花费 问如何操作将所有边删除使得花费的总和最小。分析: 建图: 将每个点拆分成两个点, i(左点) 和 i+n(右点) , 建立一个源点 s=0,汇点 u=2*n+1在源点和每个点左面的点连一条边,容量为删除出边的费用 在汇点和每个点右面的点连一条边,容量为删除入边的费用如果有 u到 v 的边,在u 和 v +n 之间连一条边,容量为无穷大 求出最大流即最小割 从源点深搜找出残流不为 0 的点,把这些点标记掉,剩下的为标记的点即为删除的顶点。 阅读全文
posted @ 2012-08-11 19:05 'wind 阅读(279) 评论(0) 推荐(0)
摘要:题意: 有一个有 N 个节点的无向图,要求找出两条从1 节点 到 n 节点两条最短且不同的路径,求出其长度和。分析: 由于是两条不同的路径,可以用最小费用最大流,因为是有重边,所以要用邻接表存储边。 建图:建立一个源点 s = 0 在 s 和 1 节点之间加一条容量为 2 费用为 0 的边, 建立一个汇点 u = n+1 在 n 和 u 之间加一条容量为 2 费用为 0 的边, 两两节点如果连通,就在之间加一条 容量为 1,费用为边的长度的双向边。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,si 阅读全文
posted @ 2012-08-11 12:38 'wind 阅读(249) 评论(0) 推荐(0)
摘要:题意: 有 N 头牛位于N个地点,知道了M 条边,这些牛现在要去 x 号牛那里聚会,问这些牛从自己的地点出发到 x 点,再回到自己的地点的所有最短路径中最长的一条,而且来的时候的路和回去的路不能相同,(因为边是单向的,肯定不同)。分析: 题意即将每头牛到 x 点的最短距离和该牛回来的最短距离相加,找出其中的最大距离。 如果以每个点为起点 ,以 x 为终点 求最短路,再加上以 x 为起点以每个牛的地点为终点的距离的话,容易超时, 可以在先求出 以 x 点为起点以各个点为终点的最小距离之后,将原图的边反转,这样以 x 为起点以其他各个点为终点的最短距离,即为以每个点为起点以 x 为终点的 的最短距 阅读全文
posted @ 2012-08-10 20:22 'wind 阅读(152) 评论(0) 推荐(0)
摘要:题意: 给一列数对应两种操作: 1 a b v, 把[a, b] 的值改为v,即A[a] = A[a+1] = ... = A[b] = v。 2 a b, 查询[a, b] 之间的相同数的连续和最大值。分析:线段树,区间合并 + 成段更新 ... int lva[maxn<<4];// 区间最左面的值 int lnu[maxn<<4]; // 区间最左面的数的个数 int rva[maxn<<4]; // 区间最右面的值 int rnu[maxn<<4]; // 区间最右面的数的个数 int mva[maxn<<4]; // 区间最 阅读全文
posted @ 2012-08-10 11:49 'wind 阅读(252) 评论(0) 推荐(0)
摘要:题意: 有N 个人站队,告诉每个人想插队的位置,要求确定最终的站队位置。分析: 越往后插队的人位置越固定,因此可以从后向前插入,每个人插入的位置为从第1 个位置起的第 pos+1 空位置。 用sum[i] 表示 I 区间的人数之和,用线段树维护即可。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))#define maxn 200005struct P{ int pos,val;}q[maxn];int sum[maxn<<3];int va[maxn<<3 阅读全文
posted @ 2012-08-09 11:01 'wind 阅读(214) 评论(0) 推荐(0)
摘要:题意: 有一个有N 个区间木板,存在最多 30 种颜色,一开始木板的颜色都为第一种颜色。 定义两种操作: Cxyc 将区间[x,y]涂成 c 颜色。 P xy询问区间[x,y]共有多少种颜色。分析: 比较典型的成段更新的线段树染色问题,使用延迟标记数组。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))#define maxn 100005int col[maxn<<3];int v[33];void creat(int l,int r,int rt){ col[rt] 阅读全文
posted @ 2012-08-08 20:10 'wind 阅读(300) 评论(0) 推荐(0)
摘要:题目:View Code Fleeting time does not blur my memory of you. Can it really be 4 years since I first saw you? I still remember, vividly, on the beautiful Zhuhai Campus, 4 years ago, from the moment I saw you smile, as you were walking out of the classroom and turned your head back, with the soft sunset 阅读全文
posted @ 2012-08-08 19:23 'wind 阅读(317) 评论(0) 推荐(0)
摘要:题意: 有 n 个矩形,求总的覆盖面积。分析: 离散化浮点数坐标,以 x 轴 建树, 将每个矩形拆分成上下两条线段,从下向上扫描。/*************************************** 离散化浮点数,把矩形分成上边和下边, ** 按 x 坐标建树,从下向上扫描 ****************************************/#include<stdio.h>#include<string.h>#include<stdlib.h>#include<algorithm>#define clr(x)memse 阅读全文
posted @ 2012-08-08 13:02 'wind 阅读(221) 评论(0) 推荐(0)
摘要:题意: 给出 n 个人,知道了每个人的成绩,和每个人想要的奖学金,要求从这些学生中找出 m (奇数)个人满足选出的人的成绩的中位数最大,且这些人总的奖学金需求要 小于等于总的奖学金数。分析: 可以先对学生按成绩降序排序,然后从位置m/2+1 到 N - m/2枚举,中位数 q[i],因此对于枚举每个中位数只要求出左面最小的 m/2个数,和右面最小的 m/2 个 数,只要 left[i-1]+q[i].money+rght[i+1] <=F ,i 即为要找的学生。 left[i] 表示从 i 个位置向左的序列中最小的 m/2个数之和,对于每次出现新的 i 值,要求出 m/2 个最小的数这个 阅读全文
posted @ 2012-08-07 20:56 'wind 阅读(271) 评论(0) 推荐(0)
摘要:题意: 从小到大排序分析:堆排序讲解:View Code “堆”定义 n个关键字序列Kl,K2,…,Kn称为(Heap),当且仅当该序列满足如下性质(简称为堆性质): (1)ki<=k(2i)且ki<=k(2i+1)(1≤i≤ n),当然,这是小根堆,大根堆则换成>=号。//k(i)相当于二叉树的非叶结点,K(2i)则是左孩子,k(2i+1)是右孩子 若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树: 树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。 大根堆和小根堆:根结点(亦称为堆顶)的关 阅读全文
posted @ 2012-08-07 16:54 'wind 阅读(291) 评论(0) 推荐(0)
摘要:题意: 有 N 个人分属于两个帮派,对应两种操作: A X Y 询问x,y 是否属于一个帮派,或两者关系不能确定。 D X Y X和Y 分属不同帮派分析: 感觉就是简化版的食物链...方法一: 加一个数组 r[i] r[i] = 0 表示 i 与祖先属于同一个帮派 r[i] = 1 表示 i 与祖先属于不同帮派View Code #include<stdio.h>#include<string.h>int f[100005];int r[100005];int find(int x){ int s; if(f[x]==-1) return x; else s... 阅读全文
posted @ 2012-08-07 15:40 'wind 阅读(201) 评论(0) 推荐(0)
摘要:题意: 有一棵有 n 个节点并以 1 为根节点的树, 一开始每个节点有 1 个苹果,定义两种操作 Q i 询问以 i 为根节点的树上有多少个苹果。 C i 如果i 这个节点上有 1 个苹果就把它摘下,否在就在这个节点装上一个苹果。分析: 可以把树上的每个节点对应到树状数组中, 对应的时候,越靠近根节点的节点管辖的数组区间范围越大, 可以利用深搜,根据访问的时间戳的顺序,依次为每个节点标记在树状数组中的下限 l[i], 因为要使得越靠近叶子节点的节点管辖区间越小,可以利用深搜回溯的特点,即越靠近叶子的节点,回溯到本身的时间差越短,这个时间差即为该节点覆盖的数组区间长度,因此每个节点覆盖的数组上. 阅读全文
posted @ 2012-08-07 13:16 'wind 阅读(186) 评论(0) 推荐(0)
摘要:题意: 一组造作: 0 n 创建一个 n*n 的矩形。 1 x y num 在(x,y)位置加上值 num。 2 l b r t 输出矩阵 l<=x<=r,b<=y<=t 内所有数值和。 3 退出。分析: 二维树状数组。#include<stdio.h>#include<string.h>int a[1025][1025];int n;int lowbit(int x){ return (x)&(-x);}void add(int x,int y,int num){ while(x<=n) { int ty=y; while(ty& 阅读全文
posted @ 2012-08-07 11:11 'wind 阅读(170) 评论(0) 推荐(0)
摘要:题意: 模拟手机的输入,手机每个按键负责一定数量的字符,知道了一些单词,和这些单词的使用频率,给出一个按键的顺序,问每个数字所在位置对应的最大可能的输入单词是哪个,如果找不到 输出‘MANUALLY‘分析:建立字典树,把单词存起来,并累加每个字母使用的频率,每出现输入的一个数字,找出那个数字上对应的字母所在位置频率最大的单词。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))char res[105];char tmp[105];int la;struct node{ int co 阅读全文
posted @ 2012-08-07 10:43 'wind 阅读(170) 评论(0) 推荐(0)
摘要:题意: 给出一个 有 n 个节点,m 条边的的有向图,求图中的次短路,如果有超过两条以上的最短路,那么次短路的长度即为最短路的长度。分析: 可以先求出最短路,并保存路径,从 i 到 j 次短路的构成可以用 i 到 点k的次短路加上k 到j 的最短路构成,而i 到 k 的次短路也是通过同样的方法求出, 因此可以通过枚举不在最短路上的边来依次推出 1 到 2..n 的次短路。#include<stdio.h>#include<string.h>#include<stdlib.h>#define INF 0x1f1f1f1fint g[1003][1003];in 阅读全文
posted @ 2012-08-06 17:38 'wind 阅读(188) 评论(0) 推荐(0)
摘要:#include<stdio.h>#include<string.h>#include<stdlib.h>#include<queue>#define clr(x)memset(x,0,sizeof(x))using namespace std;#define INF 0x1f1f1f1fstruct node{ int from,to,next,w;}e[1000000];int tot;int head[5003];void add(int s,int t,int wi){ e[tot].from=s; e[tot].to=t; e[tot] 阅读全文
posted @ 2012-08-06 15:10 'wind 阅读(220) 评论(0) 推荐(0)
摘要:题意:有以个 有 N 个节点的树形地图,问在这些顶点上最少建多少个电话杆,可以使得所有顶点被覆盖到,一个节点如果建立了电话杆,那么和它直接相连的顶点也会被覆盖到。分析:用最少的点覆盖所有的点,即为求最少支配集。 可以用树形DP。① dp[r][0] += min(dp[i][0],dp[i][1],dp[i][2]) dp[r][0]表示在自 r 顶点自身建, 以 r为根节点的树所需要的最少覆盖数。② dp[r][1] += min(dp[i][0],dp[i][1])dp[r][1]表示在r的子节点建, 以 r为根节点的树所需要的最少覆盖数。③ dp[r][2] += min(dp[i][0 阅读全文
posted @ 2012-08-06 10:03 'wind 阅读(959) 评论(0) 推荐(0)
摘要:题意 : 已知有n 个浮冰 ,和每个企鹅可以跳跃的最大距离,知道了每个浮冰的坐标,和该浮冰上一开始有的企鹅数量,和 该浮冰最多能承受的跳跃次数,跳跃次数是指从该浮冰跳出的最大次数,浮冰的编号从 0 开始,里面哪些浮冰满足 最后所有的企鹅都能够到达。分析: 建立一个超级 源点 s=0 ,将每个浮冰分成两个点,左边的点记为 1..n ,右面的点依次为 n+1..n+n,在浮冰 i 和 i+n 之间连一条从i 到 i+n的边,容量设为 浮冰 i 上的 最大跳跃次数,在源点 s 和 每块冰 i(1..n)之间连一条从s 到 i 的边,容量设为冰 i 上初始的企鹅数量,即为该点的初始流量,如果 冰 i 阅读全文
posted @ 2012-08-05 20:26 'wind 阅读(280) 评论(0) 推荐(0)
摘要:题意: 有一对 新人举办婚礼,邀请了n-1对夫妇,有一张很长的桌子,要求左右的夫妇都分别坐在桌子的两侧,且知道了 m 对 人有关系,要求新娘对面不能出现有关系的两个人。分析: 在 有关系的人之间连边,在所有夫妇之间连边,用奇数表示男的,偶数表示女的,用2-sat方法染色,最后输出不在新娘一边的人。#include<stdio.h>#include<string.h>#define op(x) ((x)=='h'?1:0)#define clr(x)memset(x,0,sizeof(x))#define min(a,b)(a)<(b)?(a):(b 阅读全文
posted @ 2012-08-04 23:56 'wind 阅读(234) 评论(0) 推荐(0)
摘要:题意: 有 N 个木桩,知道了 m 对木桩的高度差, 问从一点 a 跳到到 b所需要经过的最小高度差。分析:将 Floyed 作一点改动 ,松弛操作 变为 g[i][j]=min(g[i][j],max(g[i][k],g[k][j]))#include<stdio.h>#include<string.h>#define INF 0x1f1f1fint min(int a,int b){ return a<b?a:b;}int max(int a,int b){ return a>b?a:b;}int g[305][305];int main(){ int 阅读全文
posted @ 2012-08-04 20:07 'wind 阅读(188) 评论(0) 推荐(0)
摘要:题意: 有 N 个男生和 N 个女生,已知每个男生对每个女生的喜欢程度,和每个女生对每个男生的喜欢程度。 找到一种搭配方式使得总的满意程度最高。稳定婚姻解法: 如果男A与女C匹配,男B与女D 匹配,但是A更喜欢D,D更喜欢A,那么这个婚姻就不是稳定的。稳定婚姻问题的算法步骤大致如下:(男士优先) 1.男士先选择自己最爱的人去求婚,如果有多个男士的最爱相同,那么女士就选择更爱的那位男士,那么其他的男士在这次求婚中失败。 2.上次求婚失败的男士再选择自己次爱的女士进行求婚,如果这位女士没有匹配男士,那么这两个人就进行匹配,如果这位女士有匹配的男士,但是如果这位女士更喜欢这位正在求婚的男士,那么这位 阅读全文
posted @ 2012-08-04 18:56 'wind 阅读(538) 评论(0) 推荐(0)
摘要:题意: HAHA 早上有 n 件事情要做, 知道了有 m 个关系,每个关系 a ,b 表示a 事情必须在b 事情之前做,问做完这些事共有多少种可能的顺序。分析: 可以把题目看成是 一个有向图,其中共有多少种拓扑排序的方法。 首先图中不能有环,可以先传递闭包,看看有没有 g[i][i]=1 的情况出现,如果有则说明有环。 由于 n <=17 ,1<<17 相对较小,可以枚举所有状态进行递推。① 递归写法#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))int g[1 阅读全文
posted @ 2012-08-04 14:45 'wind 阅读(243) 评论(0) 推荐(0)
摘要:题意: 一个有 N 个连续房间的旅馆,对 m 次询问对应两种操作。 1 a 询问是不是有连续长度为a的空房间,有的话住进最左边 2 a b 将[a,a+b-1]的房间清空分析: 区间合并类线段树。update 成段更新 query 找到满足条件的最左端点#include<stdio.h>#include<string.h>#define maxn 50005int max(int a,int b){ return a>b?a:b; }int lsum[maxn<<2];int rsum[maxn<<2];int msum[maxn<& 阅读全文
posted @ 2012-08-04 11:43 'wind 阅读(169) 评论(0) 推荐(0)
摘要:题意: 给定一个无向图,图中存在一些桥,之后向图中加入Q条边,问每次加入这条边后图中剩下的桥的数量。分析: 首先对无向图求割边,并进行缩点,使之成为一棵树,这棵树上的所有边都是割边,之后对于每次询问,会连接树上的两个节点,如果这两个节点之间的边与这条边形成一个环,那么这些边就不再是割边,对于缩点后的树,先随意定出一个根,之后对每个节点记录他的父节点,以及他在这棵树中的深度,之后对于每次询问只要从叶子节点一直搜到他们的lca,把路径上的割边去掉。#include<stdio.h>#include<string.h>#include<stdlib.h>#defi 阅读全文
posted @ 2012-08-04 00:48 'wind 阅读(227) 评论(0) 推荐(0)
摘要:题意: 有两个字符串,给出 Q 个询问,每个询问有两种方式: 1 p i c 把第 p 个字符串的第i 个字符换成 字符 c, 2 i 从位置i 开始,两个字符串连续相同的子串的最大长度为多少。分析: 线段树。 数组len[rt] 保存rt 区间从最左端开始的最长子串, 合并时,如果len[rt<<1]==mid-l+1 则 len[rt]=len[rt<<1]+len[rt<<1|1] ,说明可以把右儿子区间直接接到左儿子区间上,否则由于左儿子区间与右儿子区间断开, len[rt]=len[rt<<1].#include<stdio.h& 阅读全文
posted @ 2012-08-03 21:48 'wind 阅读(195) 评论(0) 推荐(0)
摘要:题意: 给出 N 只鱼的坐标,问用半径为 1 的渔网做多可以捕到多少鱼。分析: 以每条鱼为圆心,作半径为1 的圆,枚举两两圆的交点,比较以每个交点为圆心半径 1 的渔网最多捕获的鱼数。#include<stdio.h>#include<string.h>#include<stdlib.h>#include<math.h>const double eps=1e-6;struct node{ double x,y;}q[305];double dis(node a,node b){ return (a.x-b.x)*(a.x-b.x)+(a.y-b. 阅读全文
posted @ 2012-08-03 10:59 'wind 阅读(215) 评论(0) 推荐(0)
摘要:题意:一个有 N 个节点的有向无环图, 已知有 M 条边,问最少放多少机器人可以使得图中任何一点都至少可以被其中一个机器人达到。分析: 最小路径覆盖。 因为可以经过一些点到达另一些顶点,所以需要传递闭包将每个点可达的顶点都连上边,然后求最小路径覆盖。 最小路径覆盖 = 总权 - 最大匹配#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))int g[505][505];int link[505];int v[505];int n;int find(int x){ int i; for 阅读全文
posted @ 2012-08-01 17:42 'wind 阅读(214) 评论(0) 推荐(0)