06 2013 档案
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2413思路:由于要求最少的时间,可以考虑二分,然后就是满足在limit时间下,如果地球战舰数目比外星战舰数目多,就连边,然后求最大匹配即可,判断匹配数目是否等于外星球数目,如果相等,说明可以占领,继续二分。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1526思路:floyd求传递闭包,然后就是最大匹配了,不过一开始输入没看清,被坑了将近2个小时。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define MAXN 111 8 vector<int>vet[MAXN];
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1669思路:由于要求minimize the size of the largest group,由此我们想到二分枚举,然后每一次求一下多重匹配就可以了。 1 #include 2 #include 3 #include 4 #include 5 #include 6 using namespace std; 7 #define MAXN 1010 8 #define MAXM 555 9 vectorvet[MAXN];10 bool map[MAXN][MAXN];11 int Link[MAX
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2389思路:纯裸的一个最大匹配题,不过悲摧的是以前一直用的dfs版一直过不了,TLE无数次啊,然后改成bfs就过了。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #include<cmath> 7 #include<queue> 8 using namesp
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3118思路:题目要求是去掉最少的边使得图中不存在路径长度为奇数的环,这个问题等价于在图中去掉若干条边,使得这个图成为二分图。注意到n不是很大,于是我们可以想到二进制枚举,枚举每条边的两个顶点是否在同一个集合中,若是,则删除这条边。 1 #include 2 #include 3 #include 4 #include 5 #include 6 using namespace std; 7 #define inf 1 >map; 9 int n,m;10 11 int main()12 {13
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3360思路:最小覆盖==最大匹配。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define MAXN 3333 8 vector<int>vet[MAXN]; 9 int map[MAXN][MAXN];10 int l
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4179思路:不知道怎么回事,wa了n多次,然后不知道怎么回事就过了==,还是简单的说一下思路吧:一次以起点为源点跑一遍spfa,然后以终点为起点跑一次spfa,这样我们就可以枚举difficult为maxdist的边了,设该边的端点为x,y,于是有ans=min(ans,dist1[x]+Get_Dist(x,y)+dist2[y])。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #i
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2065思路:递推:dp[len][0]表示长度为len的全部合法字符串的个数;dp[len][1]表示长度为len的,仅有A出现奇数次的字符串的个数;dp[len][2]表示长度为len的,仅有C出现奇数次的字符串的个数;dp[len][3]表示长度为len的,A,C均出现奇数次的字符串的个数。于是我们可以得到下列方程:dp[len][0]=2*dp[len-1][0]+dp[len-1][1]+dp[len-1][2];dp[len][1]=dp[len-1][0]+2*dp[len-1][1]+
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4424题意:给你一颗树,树中每条边有一权值c,对于从i节点到j节点的路径,其权值定义为该路径上边权值的最小值,于是问找到一个中心点,使得从该点到其他节点的路径权值和最大,求该最大值。思路;要使得权值和最大,容易想到对边进行从大到小排序,用一个sum来记录权值,cnt来记录节点个数,然后每次合并时取权值和较大的那个即可。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4253思路:求最小生成树是显然的,题目还多了一个限制条件,就是属于A公司的边必须有K条,于是我们可以二分来实现这个目的,找一个尽量大的mid,用A公司的每条边都加上这个mid,使得求出的最小生成树中包含A公司的边至少K条,于是花费ans=sum-K*mid。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespac
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4263思路:将红边和蓝边单独求一次生成树,求的红边最多可以加入的边数cntr,蓝边最多可以加入的边数cntb,只要k满足条件k>=(n-1-cntr)&&k<=cntb,就说明可以生成这样的spanning tree. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std;
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2818思路:Count[i]表示i下面的积木个数,路径压缩的时候更新一下即可,sum[i]表示以i为根的积木的个数。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define MAXN 30000+30 7 int parent[MAXN]; 8 int sum[MAXN],Coun
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3047思路:冲突的条件是:两个人坐在同一行,同时他们到根节点的差值等于他们之间的差值,这时就产生冲突了。于是我们可以用一个dist数组来保存节点到根的距离,而这个距离在路径压缩的时候更新一下就可以了,dist[x]+=dist[parent[x]]。然后就是合并后的距离,令r1=Find(u),r2=Find(v),于是合并时就有parent[r2]=r1,dist[r2]=dist[u]+w-dist[v]。盗用一张图: 1 #include<iostream> 2 #include&
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1558思路:主要是判断线段相交,如果相交,就是要合并了,并且修改一下sum值就可以了。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 #define MAXN 1111 8 #define eps 1e-7 9 int parent[MAX
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2144思路:合并的过程中多了一个条件,而这个条件的判断可以通过求最长公共连续子序列得到,别的和普通的并查集没什么区别,最后就是简单地判断一下集合的个数即可。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define MAXN 111 7 char str[MAXN][MAXN]; 8
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2860思路:多了一个记录每个集合最小值的value数组而已,然后判断的时候小心一点就可以了。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define MAXN 100000+100 7 int parent[MAXN]; 8 int value[MAXN]; 9 int n,m,k
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4126思路:我们可以先求最小生成树,对于最小生成树的每一条边,我们要找到它的最佳替代边,使其价值最小。具体实践方法:假设两个各自连通的部分分别为树A,树B,dp[i][j]表示树A中的点i到树B(点j所在的树的最近距离),这个很容易用dfs实现,然后通过求出的dp[i][j],再用一个dfs求出树B到树A的最近距离(就是枚举树A中的所有点 到 树B的最近距离,取其中的最小值),这个求出来的值其实就是我们要求的最佳替代边,将它保存到一个数组中即可。总的时间复杂度为O(n^2)。 1 #include.
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3938思路:对于边进行从小到大进行排序,题目要求a、b两点之间所有的路径中的最大边的最小值,在满足边的大小<=len的条件下,令r1=Find(a),r2=Find(b),若r1==r2,此时就是简单的合并,并且更新一下集合的个数(abs(parent[i])即为以i为根结点的集合的大小),若r1!=r2,此时a,b两点之间的路径的条数即为parent[r1]*parent[r2]。显然对于那些边>=len的,都要加上原先的路径数目。 1 #include<iostream>
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2120思路:简单的并查集判环应用,即如果当前的两个节点在同一个集合中,那么说明存在环了,ans++。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define MAXN 1000+10 7 int parent[MAXN]; 8 int n,m; 9 10 int Find(int
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3038思路:sum[x]表示区间[x,f[x]]的和,这个可以在路径压缩的时候更新,对于一组数据(u,v,w),令r1=Find(u),r2=Find(v),于是若r1==r2,此时u,v就有了相同的参考点,而sum[u]为区间[u,r1(r2)]的和,sum[v]为区间[v,r2(r1)]的和,于是只需判断w==sum[v]-sum[u]即可;若r1<r2,此时可以分为两种情况,(u,v,r1,r2)或者(u,r1,v,r2),对于情况1来说,此时father[r1]=r2,sum[r1]=
阅读全文
摘要:操作系统上机实习课,简单地实现了一下银行家算法==具体的算法流程就不写了== 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<algorithm> 6 using namespace std; 7 #define n 5//进程个数 8 #define m 3//资源种类 9 string safety; 10 int Available[m]={2,3,3};//可用资源向量 11 int Reques
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4160思路:最小路径覆盖,如果满足条件:wi < wj , li < lj , and hi < hj,那么i->j连边,然后就是求最大匹配。最小路径覆盖=顶点数-最大匹配。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 struct Node{ 7 int wi
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3342思路:直接拓扑排序即可。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<vector> 7 using namespace std; 8 bool map[111][111]; 9 vector<int>vet[111];10 int f
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2647思路:就是一个简单的拓扑排序,给每个节点标号,不过要注意的是访问过的节点的id应该取最大才能满足要求,然后就是要反向建边(这里wa了好多次)。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<vector> 7 using namespace std;
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2458思路:由于要求选出尽可能多的认识的人,那么我们可以反着来考虑,给不认识的女孩和男孩连边,于是问题就转化为求最大独立集。最大独立集=顶点数-最大匹配。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define MAXN 222 8
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4185思路:坐标映射建双向图,只要满足条件构成矩阵,就连边,最后求一下最大匹配即可。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define MAXN 360036 8 vector<int>vet[MAXN]; 9 c
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1507思路:这题关键是建图,我们可以把坐标映射建双向图,最后求得的最大匹配数/2就ok了。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define MAXN 10010 8 vector<int>map[MAXN]; 9
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1350http://acm.hdu.edu.cn/showproblem.php?pid=1960思路:最小路径覆盖,即如果两条路线的时间不冲突,那么就连边,最后求一下最大匹配就可以了。最小路径覆盖=顶点数-最大匹配。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include&l
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2768思路:把喜欢cat的和喜欢dog的看成两个集合,如果这两个集合有冲突,即cat.love==dog.hate或者cat.hate==dog.love,这连边,代表有矛盾,那么最后的结果不就是求一下最大独立集吗。最大独立集=顶点数-最大匹配。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<algorithm&g
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1845思路:匈牙利算法应用,900ms+险过。(好像直接n/2就行) 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define MAXN 5555 8 vector<int>map[MAXN]; 9 int n,m,ans
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2682思路:一个裸的最小生成树,先打个素数表,然后就是连边了。dfs判断是否连通,连通的话就是kruskal求最小生成树了。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 #define MAXN 666 8 struct Edge{ 9
阅读全文
摘要:题目链接 :http://acm.hdu.edu.cn/showproblem.php?pid=2128思路:这题判重比较麻烦,我是这样做的:每个状态记录炸弹数目以及爆破点的坐标映射,还要有一个访问数组来标记已经取过的炸弹的位置(下次经过就不能再取了),由于要求时间最短,可以考虑优先队列。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2242思路:Tarjan求边双连通分量,进行缩点后成树,然后就是树型dp,求一下最小差值就行了。ps:注意点:由于双向建边,DP搜索时要记录父亲,只能往下搜,不能搜该节点的父亲。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stack> 6 #include<vector> 7 using
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2732思路:如果从某一根柱子能够直接跳到迷宫的外面,那么我们就将这个点连接到汇点。对于哪些不能跳出去但是又有柱子的点,那么 我们就去按照跳跃距离搜寻有没有其他的柱子能够去跳跃,如果能够找到的话,那么连接这两点,并且将容量控制为弧尾节点的柱子数,也正是由于一条弧只能够约 束一个顶点,所以我们需要进行拆点,点内之间流量为本身柱子数。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #inclu
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1827思路:缩点后建新图,然后找入度为0的点,在入度为0的点中找颜色相同的最小的花费,将这些花费相加就是最后最小的花费了。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #include<stack> 7 using namespace std; 8 #define MA
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4463思路:由于nike与apple必须有直接的边相连,因此可以先把这条边选进去,然后就是Kruskal求最小生成树了,由于一开始已经把点nike和点apple合并了,因此kruskal选择边的时候就不会选进去了。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namesp
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3665思路:对海相邻的点进行标记即可,然后就是裸的最短路了。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 #define inf 1<<30 8 bool mark[22]; 9 bool visited[22];10 int
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2444思路:首先要判断能否构成二分图,用bfs对当前点u染色,对u的邻接点v的颜色进行判断,如果为染色,则染色后入队列,否则,判断color[v]==color[u],如果相等,说明无法构成二部图 ,直接返回false即可。最后就是简单的匈牙利直接求最大匹配就可以了,不过这儿是无向图,最后要除以2。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2376思路:引:如果暴力枚举两点再求距离是显然会超时的。转换一下思路,我们可以对每条边,求所有可能的路径经过此边的次数:设这条边两端的点数分别为A和B,那 么这条边被经过的次数就是A*B,它对总的距离和的贡献就是(A*B*此边长度)。我们把所有边的贡献求总和,再除以总路径数N*(N-1)/2,即为最 后所求。每条边两端的点数的计算,实际上是可以用一次dfs解决的。任取一点为根,在dfs的过程中,对每个点k记录其子树包含的点数(包括其自身),设点数为a[k],则k的父亲一侧的点数即为N-a[k]。这个
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4324思路:dfs搜索即可,如果当前点u的下一个点v已经访问过了,那么就判断dist[u]==dist[[v]+2,成立返回true,否则更新dist[v]=dist[u]+1,继续深搜。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2354思路:初始化step[][]==inf,然后如果当前点p.step<step[p.x][p.y],则入优先队列。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 #define inf 1<<30 8 struct N
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2819思路:有矛盾关系的可以考虑二分匹配= =只交换行或者只交换列都能得到目的,如果不能,就输出-1。建图的时候应该建有向图。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath>[ 6 using namespace std; 7 #define MAXN 111 8 int n,x; 9 in
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2831思路:按剩余时间排序即可,简单贪心。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define MAXN 111 7 struct Node{ 8 int v,d,index; 9 }node[MAXN];10 int n,t;11 bool flag;12 13 int cm
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4311思路:只会最简单的暴力枚举,枚举n/2的附近点即可。 1 #include 2 #include 3 #include 4 #include 5 #include 6 using namespace std; 7 #define MAXN 100010 8 typedef long long ll; 9 #define inf (1ll)n?n:n/2+333);43 for(int i=st;i<=ed;i++){44 ll ans=Solve(i);45 ...
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4296题意:有 n 个地板,每个地板 i 有两个权值 Wi, Si,且 PDV(i) =(ΣWj) - Si ( j 表示在 i 上面的地板)。问如何调整顺序,使得【max(PDV)】最小。思路:假设i,j相邻,并且i上面的重量为sum,若i在上面,则有pi=sum-si,pj=sum+wi-sj;若j在上面,则有pi'=sum+wj-si,pj'=sum-sj;显然有pi<pi',pj>pj',于是令pj<pi',就有sum+wi-sj&l
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4313思路:初始时一条边都不加,将所有边按权值从大到小排序,判断每一个边两端的顶点是否是均为machine节点,如果是则应删除这条边(即sum要加上这条边的权值),否则加入这条边,然后在并查集合并时尽量让根节点为machine节点。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #def
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3335思路:有矛盾的条件一般都应该往匹配这方面想:能够整除的连边,于是答案(最小路径)==|顶点个数|-最大匹配。这儿要注意的地方就是要去掉相同的数(排序一下即可),然后就是hungry算法搞定就可以了。 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861思路:缩点是显然的:What’s more, for each pair of city (u, v), if there is one way to go from u to v and go from v to u, (u, v) have to belong to a same state.然后就是建新图了,求最大匹配即可。这里有最小路径覆盖==|顶点个数|-最大匹配; 1 #include<iostream> 2 #include<cstdio> 3 #incl
阅读全文