随笔分类 - ACM题解
摘要:题目链接题目大意:给定一棵树,每个结点有一个权值,一棵树的权值为所有结点的权值和,现将这棵树分为两棵子树,要使得两子树的权值差最小。我的做法是先将无根树化为有根树,然后求每棵子树的权值,最后用一次扫描求结果。需要注意的是结果要用long long型。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #include <vector> 4 #define N 100000 5 #define MAX(a,b) ((a)>(b)?(a):(b)) 6 #define MIN(a,b) ((a)&l
阅读全文
摘要:题目链接这题Balance Act那题差不多,不过这题的数据量更大,时间有点卡,我的O(N)的算法都跑了1100多MS(时限2S)。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #include <vector> 4 #define N 50005 5 #define MAX(a,b) ((a)>(b)?(a):(b)) 6 using namespace std; 7 vector<int> dep[N]; 8 int u[2*N],v[2*N],first[N],next[
阅读全文
摘要:题目链接题目大意:给定一棵树,树的每个结点有一个权值,每个结点的权值=去掉该结点后剩余的分支中结点最多的那个分支的结点数。求树中权值最小的结点。这题CE了两次,第一次因为使用了memset没包含头文件,第二次是因为GNU C++没有头文件<memory.h>,使用<string.h>就AC了。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #include <vector> 4 #define N 20000 5 #define MAX(a,b) ((a)>(b)?(
阅读全文
摘要:题目链接这题要用左二子,右兄弟的存储结构来存树(附加一个结点0,将森林连成树),然后就是在二叉树上DP。View Code 1 #include <stdio.h> 2 #include <memory.h> 3 #define MAX(a,b) ((a)>(b)?(a):(b)) 4 #define N 205 5 int son[N],bro[N],w[N],n,m; 6 int c[N][N]; 7 void Insert(int u,int fa,int x) 8 { 9 w[u]=x;10 if(son[fa]==-1) son[fa]=u;11 els
阅读全文
摘要:题目链接没有上司的晚会,经典的树形DP题。View Code 1 #include <stdio.h> 2 #include <memory.h> 3 #define MAX(a,b) ((a)>(b)?(a):(b)) 4 #define N 6000 5 int a[N],p[N],d[N],c[N],vis[N],sums[N],sumgs[N],dmax,n; 6 int fd(int k) 7 { 8 if(!vis[k]) return d[k]=0; 9 if(d[k]) return d[k];10 return d[k]=fd(p[k])+1;1
阅读全文
摘要:题目链接题目大意:给定一棵树,求最大点独立集中点的数目。这题昨晚一开始想到可以转化为求二部图的最大匹配来做,没估计复杂度,最后超时了。后来就考虑把树分成两部分,取结点较多的那部分作为结果,提交后WA。再后来,我考虑给树定一个根结点,然后分层,统计每层的结点数目,然后再转化为DP问题去做,相当于是分层DP,结果还是WA。昨天晚上躺在床上时,突然想到曾经听说过树形DP,难道这题正是?今天翻了下刘汝佳的白书,学习了下树形DP,然后果断AC。AC的代码 1 #include <stdio.h> 2 #include <vector> 3 #define MAX(a,b) ((a
阅读全文
摘要:题目链接题目大意:给定一个只含1,2,3的数列,求排序的最小交换次数。这题说不出需要用什么算法,如果有的话,应该是贪心的思想。我的做法是,先统计1,2,3的个数,然后就知道了1,2,3应该排在哪些区间,首先将错位的两两交换(例如1在2的区间,2在1的区间),然后三个之间交换(例如1在2的区间,2在3的区间,3在1的区间)。View Code 1 #include <stdio.h> 2 #include <memory.h> 3 #define MIN(a,b) ((a)<(b)?(a):(b)) 4 #define N 1000 5 int a[N]; 6 in
阅读全文
摘要:题目链接二分查找树的模拟。不能用数组模拟,那样内存会爆掉。View Code 1 #include <stdio.h> 2 #define N 1000 3 struct node 4 { 5 int x; 6 struct node *left,*right; 7 }node[N]; 8 char f; 9 void Insert(struct node *r,struct node *p)10 {11 if(!r) return;12 if(r->x>p->x)13 {14 if(r->left) Insert(r->left,p);15 else
阅读全文
摘要:题目链接典型的DFS题,骑士周游问题。这题的关键在于字典序输出路径,要处理好搜索的顺序,另外需要注意的是,字母表示行,数字表示列。View Code 1 #include <stdio.h> 2 #include <memory.h> 3 #define N 26 4 int dx[8]={-2,-2,-1,-1,1,1,2,2}; 5 int dy[8]={-1,1,-2,2,-2,2,-1,1}; 6 char vis[N][N],ok; 7 int n,m; 8 int ans[N]; 9 void dfs(int i,int j,int cnt)10 {11 i
阅读全文
摘要:题目链接宽度优先搜索。View Code 1 #include <stdio.h> 2 #include <memory.h> 3 #include <queue> 4 #define N 300 5 using namespace std; 6 typedef pair<int,int> node; 7 queue<node> Q; 8 int dx[8]={1,1,-1,-1,2,2,-2,-2}; 9 int dy[8]={2,-2,2,-2,1,-1,1,-1};10 int n;11 int step[N][N];12 in
阅读全文
摘要:题目链接动态规划题。题目大意:给定一个二维数组,数组中每个数代表一个高度,每次只能向相邻且高度下降的方向移动,求最长的移动距离。View Code 1 #include <stdio.h> 2 #include <memory.h> 3 #define MAX(a,b) ((a)>(b)?(a):(b)) 4 #define N 100 5 int dx[4]={0,0,1,-1}; 6 int dy[4]={1,-1,0,0}; 7 int h[N][N],n,m; 8 int c[N][N]; 9 int dp(int i,int j)10 {11 int n
阅读全文
摘要:题目链接优先队列的题。进行队列弹出操作时要注意判空,如果有多case,记得清空队列。View Code 1 #include <stdio.h> 2 #include <queue> 3 #define N 30000 4 using namespace std; 5 6 priority_queue<int,vector<int>,greater<int> >qmin; 7 priority_queue<int,vector<int>,less<int> >qmax; 8 9 int a[N];1
阅读全文
摘要:题目大意:给定一个n*m的只含0和1的矩阵,从矩阵的最后一行中的某个1出发,每步只能走到相邻的且是1的格子中,求能达到的最大高度(最小行数)。这题直接DFS即可,复杂度为O(N*M)。View Code 1 #include <stdio.h> 2 #define MAX(a,b) ((a)>(b)?(a):(b)) 3 #define N 100 4 int dx[4]={0,0,1,-1}; 5 int dy[4]={1,-1,0,0}; 6 char g[N][N]; 7 int n,m,ans; 8 void dfs(int i,int j) 9 {10 int d,
阅读全文
摘要:题目链接贪心题,也是训练优先队列的好题。题目大意:给一块长木板,现要将其锯成n段,共需锯n-1次,每次锯的代价为所锯木板的长度,求最小总代价。其实也可以看成是把n段木板拼成一块,每次拼的代价为所拼木板的长度和。这就跟哈夫曼编码一样,每次选取两个最小的来拼。具体实现时用优先队列。View Code 1 #include <stdio.h> 2 #include <queue> 3 using namespace std; 4 #define INF 0x7fffffff 5 priority_queue<int,vector<int>,greater&l
阅读全文
摘要:题目链接有限制的单源最短路。题目大意:给定一个图,图中的每条边有一个长度和一个费用,给出最大费用,求在不超过最大费用的前提下的最短路(从s到e)。我的解法是BFS+优先队列,我们可以把<d,t,i>看成状态,i为结点编号,d为结点到源点的距离,t为目前剩余的费用,每次BFS时都选取d最小的状态进行扩展,直到到达目标结点。一开始,我还担心内存会爆掉,但是一下也没想到其他方法,就照这个想法写了,结果居然AC了。由于要用到优先队列,所以只好临时学了一点STL,第一次提交是忘改用c++提交,CE了一次。View Code 1 #include <stdio.h> 2 #incl
阅读全文
摘要:题目链接递推题,A[i]=A[i-1]+2*A[i-2]。需要注意的是要用long long型。View Code 1 #include <stdio.h> 2 #define N 64 3 long long a[N]; 4 int main() 5 { 6 int i; 7 a[0]=a[1]=1; 8 for(i=2;i<N;i++) a[i]=a[i-1]+(a[i-2]<<1); 9 while(~scanf("%d",&i)) printf("%lld\n",a[i-1]);10 return 0;11
阅读全文
摘要:题目链接单源最短路的变形,需要很好的理解dijkstra最短路算法的思想。View Code 1 #include <stdio.h> 2 #include <memory.h> 3 #define MIN(a,b) ((a)<(b)?(a):(b)) 4 #define MAX(a,b) ((a)>(b)?(a):(b)) 5 #define N 1000 6 int g[N][N],w[N],n,m; 7 char vis[N]; 8 void dijkstra() 9 {10 int i,v,k,max;11 memset(vis,0,sizeof(v
阅读全文
摘要:题目链接最短路,直接dijkstra水之,注意重边。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #define MIN(a,b) ((a)<(b)?(a):(b)) 4 #define N 1000 5 #define INF 100000 6 int g[N][N],dist[N],n,m; 7 char vis[N]; 8 void dijkstra() 9 {10 int i,v,k,min;11 memset(vis,0,sizeof(vis));12 for(i=0;i<n;i++)
阅读全文
摘要:题目链接最短路的题,这题时间限制较严,第一次用dijkstra果断挂掉,后来改用SPFA写,由于我用的数据结构是动态链表,所以还是TLE,改为静态链表后就AC了。在这个过程中还贡献了一次WA,因为最后结果用32位会溢出,题中说的总价格不会超过1000000000是单个最短路不会超,而最后的结果是n-1个结点的最短路之和。View Code 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <memory.h> 4 #define INF 1000000001 5 #define N 1000001 6
阅读全文
摘要:题目链接最短路的题,直接用dijkstra即可。此题比较有技巧性的地方在数据读入的处理,题中给出的是邻接矩阵的下三角,其中不直接邻接的边用字符x表示,其他地方用整数表示边长。具体做法见代码(参考了discuss)。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #define MIN(a,b) ((a)<(b)?(a):(b)) 4 #define MAX(a,b) ((a)>(b)?(a):(b)) 5 #define N 101 6 #define INF 0x7ffffff 7 int g[
阅读全文

浙公网安备 33010602011771号