コード例 #1
0
int main()
{
	int i,j,k,pos,xtmp,ytmp,source,sink,curVer;
	FILE *fin  = fopen ("project1.in", "r");
	fscanf(fin,"%d %d",&verSum,&edgSum);

	for(i=0;i<verSum;i++)
	{
		fscanf(fin,"%d %d %d",&pos,&xtmp,&ytmp);
		vertices[pos].pos=(xtmp<<16)|ytmp;
		vertices[pos].is=1;
	}

	for(i=0;i<edgSum;i++)
	{
		fscanf(fin,"%d %d",&tmp[i].pos1,&tmp[i].pos2);
		vertices[tmp[i].pos1].limit++;
		vertices[tmp[i].pos2].limit++;
	}
	i=start();

	vertices[i].suffix=0;
	for(k=1;k<verSum;k++)
	{
		j=next(i);
		vertices[j].suffix=vertices[i].suffix+vertices[i].limit;
		vertices[i].limit=vertices[i].suffix;
		i=j;
	}
	vertices[i].limit=vertices[i].suffix;
	for(i=0;i<edgSum;i++)
	{
		edges[vertices[tmp[i].pos1].limit++]=tmp[i].pos2;
		edges[vertices[tmp[i].pos2].limit++]=tmp[i].pos1;
	}
	while(1)
	{
		printf("input two place:");
		scanf("%d %d",&source,&sink);
		visit[source]=reach[source]=1;
		heapsize=0;
		push1(source);
		push2(source);
		cost[source]=0;
		curVer=source;
		while(curVer!=sink)
		{
			for(i=vertices[curVer].suffix;i<vertices[curVer].limit;i++)
			{
				if(visit[edges[i]])
					continue;
				if(reach[edges[i]]==0)
				{
					cost[edges[i]]=cost[curVer]+distance(vertices[curVer].pos,vertices[edges[i]].pos);
					reach[edges[i]]=1;
					push2(edges[i]);
					Insert(edges[i]);
					prefix[edges[i]]=curVer;
				}
				else if(cost[edges[i]]>cost[curVer]+distance(vertices[curVer].pos,vertices[edges[i]].pos))
				{
					cost[edges[i]]=cost[curVer]+distance(vertices[curVer].pos,vertices[edges[i]].pos);
					Update(edges[i]);
					prefix[edges[i]]=curVer;
				}
			}
			if(heapsize==0)
			{
				break;
			}
			curVer=HeapMin();
			visit[curVer]=1;
			push1(curVer);
		}
		while(Empty1())
		{
			pop1();
		}
		while(Empty2())
		{
			pop2();
		}
		if(curVer==sink)
		{
			printf("distance:%lf\n",cost[sink]);
			while(curVer!=source)
			{
				push(curVer);
				curVer=prefix[curVer];
			}
			push(source);
			printf("route:");
			while(Empty())
			{
				pop();
			}
			printf("\n");
		}
		else
		{
			printf("NULL\n");
		}
	}
	return 0;
}
コード例 #2
0
ファイル: arith01.c プロジェクト: nilqed/ReduceAlgebra
static Lisp_Object plusbb(Lisp_Object a, Lisp_Object b)
/*
 * add two bignums.
 */
{
    int32_t la = bignum_length(a),
          lb = bignum_length(b),
          i, s, carry;
    Lisp_Object c, nil;
    if (la < lb)    /* maybe swap order of args */
    {   Lisp_Object t = a;
        int32_t t1;
        a = b; b = t;
        t1 = la; la = lb; lb = t1;
    }
/*
 * now (a) is AT LEAST as long as b.  I have special case code for
 * when both args are single-word bignums, since I expect that to be
 * an especially common case.
 */
    if (la == CELL+4)    /* and hence b also has only 1 digit */
    {   int32_t va = bignum_digits(a)[0],
              vb = bignum_digits(b)[0],
              vc = va + vb;
        if (signed_overflow(vc)) /* we have a 2-word bignum result */
        {   Lisp_Object w = getvector(TAG_NUMBERS, TYPE_BIGNUM, CELL+8);
            errexit();
            bignum_digits(w)[0] = clear_top_bit(vc);
            bignum_digits(w)[1] = top_bit_set(vc) ? -1 : 0;
            if (!SIXTY_FOUR_BIT) bignum_digits(w)[2] = 0;
            return w;
        }
/*
 * here the result fits into one word - maybe it will squash down into
 * a fixnum?
 */
        else
        {   vb = vc & fix_mask;
            if (vb == 0 || vb == fix_mask) return fixnum_of_int(vc);
            else return make_one_word_bignum(vc);
        }
    }
    push2(a, b);
    c = getvector(TAG_NUMBERS, TYPE_BIGNUM, la);
    pop2(b, a);
    errexit();
    la = (la-CELL)/4 - 1;
    lb = (lb-CELL)/4 - 1;
    carry = 0;
/*
 * Add all but the top digit of b
 */
    for (i=0; i<lb; i++)
    {   carry = bignum_digits(a)[i] + bignum_digits(b)[i] + top_bit(carry);
        bignum_digits(c)[i] = clear_top_bit(carry);
    }
    if (la == lb) s = bignum_digits(b)[i];
    else
/*
 * If a is strictly longer than b I sign extend b here and add in as many
 * copies of 0 or -1 as needbe to get up to the length of a.
 */
    {   s = bignum_digits(b)[i];
        carry =  bignum_digits(a)[i] + clear_top_bit(s) + top_bit(carry);
        bignum_digits(c)[i] = clear_top_bit(carry);
        if (s < 0) s = -1; else s = 0;
        for (i++; i<la; i++)
        {   carry = bignum_digits(a)[i] + clear_top_bit(s) + top_bit(carry);
            bignum_digits(c)[i] = clear_top_bit(carry);
        }
    }
/*
 * the most significant digit is added using signed arithmetic so that I
 * can tell if it overflowed.
 */
    carry = bignum_digits(a)[i] + s + top_bit(carry);
    if (!signed_overflow(carry))
    {
/*
 * Here the number has not expanded - but it may be shrinking, and it can
 * shrink by any number of words, all the way down to a fixnum maybe.  Note
 * that I started with at least a 2-word bignum here.
 */
        int32_t msd;
        bignum_digits(c)[i] = carry;
        if (carry == 0)
        {   int32_t j = i-1;
            while ((msd = bignum_digits(c)[j]) == 0 && j > 0) j--;
/*
 * ... but I may need a zero word on the front if the next word down
 * has its top bit set... (top of 31 bits, that is)
 */
            if ((msd & 0x40000000) != 0)
            {   j++;
                if (i == j) return c;
            }
            if (j == 0)
            {   int32_t s = bignum_digits(c)[0];
                if ((s & fix_mask) == 0) return fixnum_of_int(s);
            }
/*
 * If I am shrinking by one word and had an even length to start with
 * I do not have to mess about so much.
 */
            if ((SIXTY_FOUR_BIT && (j == i-1) && ((i & 1) != 0)) ||
                (!SIXTY_FOUR_BIT && (j == i-1) && ((i & 1) == 0)))
            {   numhdr(c) -= pack_hdrlength(1L);
                return c;
            }
            numhdr(c) -= pack_hdrlength(i - j);
            if (SIXTY_FOUR_BIT)
            {   i = (i+2) & ~1;
                j = (j+2) & ~1;     /* Round up to odd index */
            }
            else
            {   i = (i+1) | 1;
                j = (j+1) | 1;     /* Round up to odd index */
            }
/*
 * I forge a header word to allow the garbage collector to skip over
 * (and in due course reclaim) the space that turned out not to be needed.
 */
            if (i != j) bignum_digits(c)[j] = make_bighdr(i - j);
            return c;
        }
/*
 * Now do all the same sorts of things but this time for negative numbers.
 */
        else if (carry == -1)
        {   int32_t j = i-1;
            msd = carry;    /* in case j = 0 */
            while ((msd = bignum_digits(c)[j]) == 0x7fffffff && j > 0) j--;
            if ((msd & 0x40000000) == 0)
            {   j++;
                if (i == j) return c;
            }
            if (j == 0)
            {   int32_t s = bignum_digits(c)[0] | ~0x7fffffff;
                if ((s & fix_mask) == fix_mask) return fixnum_of_int(s);
            }
            if ((SIXTY_FOUR_BIT && (j == i-1) && ((i & 1) != 0)) ||
                (!SIXTY_FOUR_BIT && (j == i-1) && ((i & 1) == 0)))
            {   bignum_digits(c)[i] = 0;
                bignum_digits(c)[i-1] |= ~0x7fffffff;
                numhdr(c) -= pack_hdrlength(1);
                return c;
            }
            numhdr(c) -= pack_hdrlength(i - j);
            bignum_digits(c)[j+1] = 0;
            bignum_digits(c)[j] |= ~0x7fffffff;
            if (SIXTY_FOUR_BIT)
            {   i = (i+2) & ~1;
                j = (j+2) & ~1;     /* Round up to odd index */
            }
            else
            {   i = (i+1) | 1;
                j = (j+1) | 1;     /* Round up to odd index */
            }
            if (i != j) bignum_digits(c)[j] = make_bighdr(i - j);
            return c;
        }
        return c;
    }
    else
    {   bignum_digits(c)[i] = carry;
        return lengthen_by_one_bit(c, carry);
    }
}