摘要:
题大意:给出n个点,编号1~n,给出至少n-1条边。问在需要增加几条边是该图成为双连通图。因为至少有n-1条边,所以一定是连通图,利用tarjan算法找出双连通分量,如果我们把每个双连通分量看成一个顶点,那么就构成了一棵树,再求出叶子的个数m,(m+1)/2就是答案了。我不解的是这道题需要除去重边才能AC........代码如下:#include<iostream>#include<vector>#include<cstring>using namespace std;vector <int> map[5001];int pre[5001],lo 阅读全文
摘要:
题意:给你一些单词,能否将这些单词首尾连接起来,即前一个单词的最后一个字母和后一个单词的第一个字母相同,若能输出该序列,若有多种则按字典序输出该序列。如果将每一个单词的首字母和尾字母看成节点,每个单词看成一个线段的话,若满足上述条件,就会构成一个欧拉图,然后就找出符合条件的欧拉路径。(1)构图。以为要按字典序输出,所以单词输入完毕后,进行一趟排序,有大到小排,若采用头插法,邻接表建立后,后面的节点就会自然就会按字典序排好。(2)判断有没有欧拉路径。作为有向图,有欧拉路径的从分条件是:在连通的前提下,始点的出度比入度大一且终点的入度比出度大一且其他的顶点出度等于入度,或者所有顶点出度等于入度。( 阅读全文
摘要:
自己总算真正独立的做了一道题,我的思路是这样的:将每一个区域抽象成一个节点,结果就是每个club成员到某一点的最小距离之和。关键就是构图了,每一块相邻的区域,就是直连的两节点,也就是说原图中的每一条边有且仅关联两个区域。在构造图的过程中需要保留club的每个成员可以出发的区域。重新构造图之后对每个顶点进行一次广搜找出最小值就行了。代码如下:#include<iostream>#include<queue>#include<vector>#include<cstring>using namespace std;#define MAX_INT 123 阅读全文
摘要:
大致题意:将一条海岸线看成X轴,X轴上面是大海,海上有若干岛屿,给出雷达的覆盖半径和岛屿的位置,要求在海岸线上建雷达,在雷达能够覆盖全部岛屿情况下,求雷达的最少使用量。本题一看就用贪心做,怎么贪呢?先研究一下每个岛屿,设岛屿到海岸线的垂直距离为d,雷达的覆盖半径为k,若d>k,直接输出-1,若d<=k,则雷达的建造有一个活动区间[x1,x2](用平面几何可以求得出来)。因此,在可以覆盖的情况下每个岛屿都有一个相应的活动区间。该问题也就转变成了最少区间选择问题即:在n个区间中选择一个区间集合,集合中的各个区间都不相交,集合中元素的个数就是答案了。代码如下:#include<io 阅读全文
摘要:
题意大致是:在一个序列里面,每个元素都是个数字序列,若该数字序列序号为j,则该序列就是1234.....j;输出这个总序列的第i个数字。先把前八十个字符写出来:11212312341234512345612345671234567812345678912345678910123456789101112345678910可以看出每个元素序列所具有的数字个数为该元素序列的位序加一。我的思路是这样的:先找出的i个数字所在的元素序列N,然后再找出第i个数字在第N个元素序列的第M个数字里,然后再求出是M里的那个字符个数字。代码如下:#include<stdio.h>#include<m 阅读全文
摘要:
题意:在几个区间里面,挑选出几个数字组成一个集合,使得每个区间都至少有两个数字在这个集合里面,求这个集合的最少数字个数。用贪心来做,开始我是按照每个区间的左端点进行排序,感觉需要考虑多种情况,弄了很长时间没弄出来。然后我有换一种方法来做:按每个区间的右端点从小到大排序,对于每个区间,先查看该区间内有没有数字被选过,若选过则选了几个。若没有被选过则应该选该区间的最后两个数字,若选了一个则选该区间的最后一个数字。具体代码如下:#include<iostream>using namespace std;struct node{ int x; int y;}a[10001];int ss[ 阅读全文
摘要:
其实也就是求打完boss之前的所有character剩下PH的最大值,在和boss比较,若大于boss则赢,否则则输。打boss之前的所有角色的顺序不同,剩余的PH则不同。所以将前面的n-1个角色全排列就有2^(n-1)种可能。这几乎是不可能求出来的。每个角色在打的过程之中有两种可能打和不打,打用1表示,不打用0表示,那么20个数就可以用20位来表示,所以0~2^(n-1)每个数都表示一个状态,每个数之间都可以互相转化。假设dp[i][j]表示打j状态为i的剩余PH,那么状态转移方程就可以写为:dp[i][j]=max{dp[i][j],dp[i-j][k]+a[j][1]-a[j][0]}; 阅读全文
摘要:
题大意是:给你一棵节点为n的树,问至少砍几刀可以孤立出一棵节点为m的子树。设d[i][j]为以i为根节点孤立出节点为j的子树至少需要砍得次数(注意:这个子树是包括根节点i的)。接下来再说说怎么得到状态转移方程:(1)当j为1的话,d[i][1]=节点i孩子的个数;(2)若以i的孩子son[i]为根的子树不在以i为根节点孤立出节点数为j的子树的内部,则有没有以son[i]为根的子树无所谓;若以son[i]为根节点的子树有k个节点在以i为根孤立出节点数为j的子树中则整个树分成两部分,此时,d[i][j]=d[i][j-k]+d[son[i]][k]-1;之所以减一是因为两个分开的子树重组在一起需要 阅读全文
摘要:
Poj1012约瑟夫环问题本题是约瑟夫环的变形那么先说说约瑟夫问题的数学方法 无论是用链表实现还是用数组实现都有一个共同点:要模拟整个游戏过程,不仅程序写起来比较烦,而且时间复杂度高达O(nm),当n,m非常大(例如上百万,上千万)的时候,几乎是没有办法在短时间内出结果的。我们注意到原问题仅仅是要求出最后的胜利者的序号,而不是要读者模拟整个过程。因此如果要追求效率,就要打破常规,实施一点数学策略。 为了讨论方便,先把问题稍微改变一下,并不影响原意: 问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编号。我们知道第一个人(编号一定是 阅读全文