摘要:
HDU_1385这个题目又使我获益不少。由于后续的查询工作都是对同一个图而言的,因此用Floyd算法扫一遍图就可以了。为了辅助打印路径,我们引入一个数组path[i][j]表示由i到j首先要经过的城市。一开始把所有的path[i][j]都初始化成j并没有什么不妥,尽管其中有些path[i][j]的值是错误的,但凡是错误的值,在之后运算的过程中都不用到,因为如果path[i][j]是错误的,那么必然f[i][j]是INF。#include<stdio.h>#include<string.h>int f[1010][1010],path[1010][1010],b[1010 阅读全文
摘要:
HDU_2544 直接用队列优化的Bellman-Ford算法求到各个点的最短路即可。#include<stdio.h>#include<string.h>int N,M,G[110][110],d[110];int q[110],inq[110];int init(){ int i,A,B,C; scanf("%d%d",&N,&M); if(!N&&!M) return 0; memset(G,0,sizeof(G)); for(i=0;i<M;i++) { scanf("%d%d%d", 阅读全文
摘要:
HDU_2066 直接用队列优化的Bellman-Ford算法求到各个点的最短路,然后再找到各个想去的地方的最短路的最小值即可。#include<stdio.h>#include<string.h>int q[1010],inq[1010];int G[1010][1010],d[1010];int main(){ int i,j,k,u,v,t,T,S,D,n,ans,front,rear; while(scanf("%d%d%d",&T,&S,&D)==3) { memset(G,0,sizeof(G)); n=0; fo 阅读全文
摘要:
POJ_1182这个题目在看了别人的解法之后不由地感叹原来并查集也可以这么用。首先,由于A、B、C三种生物之间存在着食物链的关系,如果单单用并查集p[]是解决不了问题了,这时还需要一个附加的数组r[]来表示x和p[x]的关系,我选用的关系为0代表x和p[x]同类,1代表x吃p[x],2代表p[x]吃x。之后难点一共有下面几处:①并查集的查找和路径压缩。我们在压缩路径的时候必然要去找x和find(x)之间的关系,而x和find(x)有可能隔了很多层,因此我们需要从find(x)开始自底向上依次更新r[],有点类似深搜的回溯。在更新关系的时候运用到了类似向量的思考模式,比如我想知道a与c的关系,而 阅读全文
摘要:
UVA_311这个题目可以直接模拟装箱的过程,并且要先装大的。①每个6*6的都占一个箱子。②每个5*5的放在一个箱子里,同时里面还能装11个1*1的。③每个4*4的放在一个箱子里,同时里面还能装5个2*2的,如果2*2的不够了,那么还能放1*1的。④每4个3*3的放在一个箱子里,如果还剩余3*3的,则要看剩余的数目分别进行讨论。⑤最后如果还剩下了2*2和1*1的,再装这些。 同时,在装2*2和1*1都可以的情况下,我们优先装2*2。这里还有一个小技巧,就是我们可以假设2*2是充足的,万一到最后2*2成了负数,我们用1*1去补就可以了,这样就不用考虑2*2是否不够的问题了。所以比如在装4*4的时 阅读全文
摘要:
UVA_10020 这个是刘汝佳白书上的例题,贪心策略就是按左端点对区间排序后依次扫描,在覆盖当前指定点的前提下使右端尽可能覆盖更大的区域。具体的思路可以参考刘汝佳白书的P154。#include<stdio.h>#include<string.h>#include<stdlib.h>int q[5010],r[100010],L[100010],R[100010];int cmp(const void *_p,const void *_q){ int *p=(int *)_p; int *q=(int *)_q; return L[*p]-L[*q]; } 阅读全文
摘要:
UVA_108为了充分利用计算过的结果,我们可以先枚举矩形左上顶点的位置,再枚举矩形的大小。同时,在计算矩形的元素和时,也要充分利用子矩形的元素和。#include<stdio.h>#include<string.h>int a[110][110],b[110],c[110];int main(){ int i,j,k,n,x,y,ans; while(scanf("%d",&n)==1) { for(i=0;i<n;i++) for(j=0;j<n;j++) scanf("%d",&a[i][j]); 阅读全文
摘要:
UVA_10245这个题目又是对我传统思维的一个撞击,一开始是怎么也想象不到会存在N^2的复杂度还小的算法,后来看了别人的博客之后才发现原来这个题目要用分治的思想。首先我们把坐标按x升序进行排列,然后定义L、R分别为区间的左右端点(L、R均代表点的标号),mid为区间中点,我们可以先分别暴力求出在[L,mid]、[mid,R]中最短的线段,不妨设其为min,当然最短线段还可能是两个点分别在两个区间之中,但如果存在这样的最短线段,那么线段的两个端点一定会在区间[a,b]中,并且x[mid]-x[a]>=min,x[b]-x[mid]>=min,因为两点之间的距离大于等于两点横坐标差的 阅读全文
摘要:
UVA_10700我们可以猜到最大值一定是先算和后算积,最小值一定是先算积后算和,因为a*b+c<=a*(b+c)。此外,这个题目数据有可能比较大,所以要采用long long int或者double来处理数据。#include<stdio.h>#include<string.h>#include<ctype.h>char b[1000];double stack[10000];int main(){ int i,j,k,t,head,top; double d,min,max,temp; char flag; scanf("%d" 阅读全文
摘要:
UVA_10487 将所有和算出来之后进行排序,再二分查找即可。#include<stdio.h>#include<string.h>#include<stdlib.h>int cmp(const void *_p,const void *_q){ int *p=(int *)_p; int *q=(int *)_q; return *p-*q;}int a[1010],s[1000010];int main(){ int i,j,k,n,m,N,t,min,mid,max; t=0; while(1) { scanf("%d",& 阅读全文