Dijkstra+二叉堆解Sweet Butter

 
 

Sweet Butter

Greg Galperin -- 2001

Farmer John has discovered the secret to making the sweetest butterin all of Wisconsin: sugar. By placing a sugar cube out in thepastures, he knows the N (1 <= N <= 500) cows will lick it and thuswill produce super-sweet butter which can be marketed at betterprices. Of course, he spends the extra money on luxuries for thecows.

FJ is a sly farmer. Like Pavlov of old, he knows he can train thecows to go to a certain pasture when they hear a bell. He intends toput the sugar there and then ring the bell in the middle of theafternoon so that the evening's milking produces perfect milk.

FJ knows each cow spends her time in a given pasture (not necessarilyalone). Given the pasture location of the cows and a description ofthe paths that connect the pastures, find the pasture in which to placethe sugar cube so that the total distance walked by the cows when FJrings the bell is minimized. FJ knows the fields are connected well enoughthat some solution is always possible.

PROGRAM NAME: butter

INPUT FORMAT

  • Line 1: Three space-separated integers: N, the number of pastures: P (2 <= P <=800), and the number of connecting paths: C (1 <= C <= 1,450). Cowsare uniquely numbered 1..N. Pastures are uniquely numbered 1..P.
  • Lines 2..N+1: Each line contains a single integer that is the pasture number in whicha cow is grazing. Cow i's pasture is listed on line i+1.
  • Lines N+2..N+C+1: Each line contains three space-separated integers that describe a singlepath that connects a pair of pastures and its length. Paths may betraversed in either direction. No pair of pastures is directly connectedby more than one path. The first two integers are in the range 1..P; thethird integer is in the range (1..225).

SAMPLE INPUT (file butter.in)

3 4 5
2
3
4
1 2 1
1 3 5
2 3 7
2 4 3
3 4 5

INPUT DETAILS

This diagram shows the connections geometrically:
          P2  
 P1 @--1--@ C1
     \    |\
      \   | \
       5  7  3
        \ |   \
         \|    \ C3
       C2 @--5--@
          P3    P4

OUTPUT FORMAT

  • Line 1: A single integer that is the minimum distance the cows must walk toa pasture with a sugar cube.

SAMPLE OUTPUT (file butter.out)

8

OUTPUT DETAILS:

Putting the cube in pasture 4 means: cow 1 walks 3 units; cow 2 walks 5
units; cow 3 walks 0 units -- a total of 8.


分析

用邻接表存储路径,再用Dijkstra求出每个牧场作为中心的和,同时用小顶堆优化。
我终于吃到你了,香甜的黄油。
http://www.acmerblog.com/dijkstras-algorithm-adjacency-list-5882.html
 

运行结果

Executing...
   Test 1: TEST OK [0.008 secs, 3512 KB]
   Test 2: TEST OK [0.008 secs, 3512 KB]
   Test 3: TEST OK [0.003 secs, 3512 KB]
   Test 4: TEST OK [0.008 secs, 3512 KB]
   Test 5: TEST OK [0.016 secs, 3512 KB]
   Test 6: TEST OK [0.032 secs, 3512 KB]
   Test 7: TEST OK [0.068 secs, 3512 KB]
   Test 8: TEST OK [0.111 secs, 3512 KB]
   Test 9: TEST OK [0.186 secs, 3512 KB]
   Test 10: TEST OK [0.205 secs, 3512 KB]

All tests OK.


通过代码

/*
ID: c1033311
LANG: C++
TASK: butter
*/
#include<stdio.h>
#include<stdlib.h>
//#include<string.h>  //一定要注释掉才能通过编译
#define MAX 0x7FFFFFFF



/******************* 单链表中的元素 *******************/
struct Node
{
	int pp;
	int ww;
	struct Node *next; 
};



/******************* 堆中元素(小顶堆,下标从1开始)*******************/
struct{
	int p;
	int w;
}heap[801];


int sum;   //堆中元素的数量和
int index[802];  //index[i]为牧场i在堆中的下标


/******************* 初始化堆 *******************/
void init_heap(int n,int start){  //n为牧场总数,start为开始牧场,它不在堆中
	int i,j;
	for(i=1,j=1;i<=n+1;++i)
		if(i!=start)
		{
			heap[j].p=i;
			heap[j].w=MAX;
			index[i]=j;
			++j;
		}

	heap[j].p=start;
	heap[j].w=0;
	index[start]=j;

	sum=n-1;
}



/******************* 交换堆中下标为i,j的两个元素 *******************/
void exchange_heap(int i,int j)
{
	int t,dt;

	index[heap[i].p]=j;
	index[heap[j].p]=i;

	t=heap[i].p;
	dt=heap[i].w;

	heap[i].p=heap[j].p;
	heap[i].w=heap[j].w;

	heap[j].p=t;
	heap[j].w=dt;
}



/******************* 上浮 *******************/
void up_heap(int i,int dis){  //i牧场的距离减小到dis

	int n=index[i];

	while((n/2)>=1 && dis<heap[n/2].w) //上浮
	{
		heap[n].w=heap[n/2].w;	
		heap[n].p=heap[n/2].p;
		index[heap[n/2].p]=n;
		n/=2;
	}

	heap[n].w=dis; //插入
	heap[n].p=i;
	index[i]=n;
}



/******************* 下沉 *******************/
void down_heap(int i,int dis){  //i牧场的距离增大到dis

	int n=index[i];
	int m;

	while((2*n<=sum) && (dis>heap[2*n].w || dis>heap[2*n+1].w)) //下沉,堆最后有个虚拟牧场避免越界
	{
		m=heap[2*n].w<heap[2*n+1].w?2*n:2*n+1;
			
		heap[n].w=heap[m].w;	
		heap[n].p=heap[m].p;
		index[heap[m].p]=n;
		n=m;
	}

	heap[n].w=dis; //插入
	heap[n].p=i;
	index[i]=n;
}



int main(){
	FILE *fin=fopen("butter.in","r");
	FILE *fout=fopen("butter.out","w");
	
	
	int N,P,C;
	struct Node *E[801]={NULL}; //从1开始
	int min_sum=MAX,temp;  //从一点出发到其它点的和
	int cow[500];
	int i,j,a,b,c;



	fscanf(fin,"%d%d%d",&N,&P,&C);

	for(i=0;i<N;++i)
		fscanf(fin,"%d",&cow[i]);

	for(i=0;i<C;++i)  //建立单链表
	{
		fscanf(fin,"%d%d%d",&a,&b,&c);

		struct Node *node=(Node*)malloc(sizeof(Node));
		node->pp=b;
		node->ww=c;
		node->next=E[a];  //头插法
		E[a]=node;

		node=(Node*)malloc(sizeof(Node));
		node->pp=a;
		node->ww=c;
		node->next=E[b];  //头插法
		E[b]=node;
	}

	

	for(i=1;i<=P;++i) //枚举所有的牧场作为中心点
	{
		int now=i;

		init_heap(P,now);

		for(j=1;j<P;++j)  //更新牧场i到其它P-1个牧场的距离
		{
			Node *e=E[now];
			while(e!=NULL)
			{
				if(index[e->pp]<=sum && heap[index[e->pp]].w>heap[index[now]].w+e->ww)
					up_heap(e->pp,heap[index[now]].w+e->ww);

				e=e->next;
			}//end while
	

			now=heap[1].p;
			exchange_heap(1,sum);
			exchange_heap(sum,sum+1);
			--sum;  //删除当前距离最小的牧场

			down_heap(heap[1].p,heap[1].w);
		}

		temp=0;
		for(j=0;j<N;++j)
			temp+=heap[index[cow[j]]].w;
	
		
		if(temp<min_sum)
			min_sum=temp;
	}
	


	fprintf(fout,"%d\n",min_sum);

	return 0;
}

如果

不注释掉#include<string.h>的话,会出现以下情况。因为index[]和string.h中的一个函数声明冲突,真见鬼。详情请看《C专家编程》5.4警惕Interpositioning(P102)


USER: Cao xiao [c1033311]
TASK: butter
LANG: C++

Compiling...
Compile error: your program did not compile correctly:

program.c:21:10: warning: anonymous type with no linkage used to declare variable '<anonymous struct> heap [801]' with linkage [enabled by default] }heap[801];          ^
      --> 20: 	int w;
      --> 21: }heap[801];
program.c:23:14: error: 'int index [802]' redeclared as different kind of symbol int index[802];  //index[i]i              ^
      --> 22: int sum;   //¶ÑÖÐÔªËصÄÊýÁ¿ºÍ
      --> 23: int index[802];  //index[i]ΪÄÁ³¡iÔÚ¶ÑÖеÄϱê
In file included from program.c:8:0:
/usr/include/string.h:482:1: error: previous declaration of 'const char* index(const char*, int)' index (const char *__s, int __c) __THROW ^
program.c: In function 'void init_heap(int, int)':
program.c:32:11: error: invalid types '<unresolved overloaded function type>[int]' for array subscript    index[i]=j;           ^
      --> 31: 			heap[j].w=MAX;
      --> 32: 			index[i]=j;
program.c:37:13: error: invalid types '<unresolved overloaded function type>[int]' for array subscript  index[start]=j;             ^
      --> 36: 	heap[j].w=0;
      --> 37: 	index[start]=j;
program.c: In function 'void exchange_heap(int, int)':
program.c:44:17: error: invalid types '<unresolved overloaded function type>[int]' for array subscript  index[heap[i].p]=j;                 ^
      --> 43: 	int t,dt;
      --> 44: 	index[heap[i].p]=j;
program.c:45:17: error: invalid types '<unresolved overloaded function type>[int]' for array subscript  index[heap[j].p]=i;                 ^
      --> 44: 	index[heap[i].p]=j;
      --> 45: 	index[heap[j].p]=i;
program.c: In function 'void up_heap(int, int)':
program.c:55:15: error: invalid types '<unresolved overloaded function type>[int]' for array subscript  int n=index[i];               ^
      --> 54: void up_heap(int i,int dis){  //iÄÁ³¡µÄ¾àÀë¼õСµ½dis
      --> 55: 	int n=index[i];
program.c:60:20: error: invalid types '<unresolved overloaded function type>[int]' for array subscript   index[heap[n/2].p]=n;                    ^
      --> 59: 		heap[n].p=heap[n/2].p;
      --> 60: 		index[heap[n/2].p]=n;
program.c:65:9: error: invalid types '<unresolved overloaded function type>[int]' for array subscript  index[i]=n;         ^
      --> 64: 	heap[n].p=i;
      --> 65: 	index[i]=n;
program.c: In function 'void down_heap(int, int)':
program.c:69:15: error: invalid types '<unresolved overloaded function type>[int]' for array subscript  int n=index[i];               ^
      --> 68: void down_heap(int i,int dis){  //iÄÁ³¡µÄ¾àÀëÔö´óµ½dis
      --> 69: 	int n=index[i];
program.c:77:18: error: invalid types '<unresolved overloaded function type>[int]' for array subscript   index[heap[m].p]=n;                  ^
      --> 76: 		heap[n].p=heap[m].p;
      --> 77: 		index[heap[m].p]=n;
program.c:82:9: error: invalid types '<unresolved overloaded function type>[int]' for array subscript  index[i]=n;         ^
      --> 81: 	heap[n].p=i;
      --> 82: 	index[i]=n;
program.c: In function 'int main()':
program.c:121:19: error: invalid types '<unresolved overloaded function type>[int]' for array subscript     if(index[e->pp]<=sum && heap[index[e->pp]].w>heap[index[now]].w+e->ww)                   ^
      --> 120: 			{
      --> 121: 				if(index[e->pp]<=sum && heap[index[e->pp]].w>heap[index[now]].w+e->ww)
program.c:121:45: error: invalid types '<unresolved overloaded function type>[int]' for array subscript     if(index[e->pp]<=sum && heap[index[e->pp]].w>heap[index[now]].w+e->ww)                                             ^
program.c:121:64: error: invalid types '<unresolved overloaded function type>[int]' for array subscript     if(index[e->pp]<=sum && heap[index[e->pp]].w>heap[index[now]].w+e->ww)                                                                ^
program.c:122:34: error: invalid types '<unresolved overloaded function type>[int]' for array subscript      up_heap(e->pp,heap[index[now]].w+e->ww);                                  ^
      --> 121: 				if(index[e->pp]<=sum && heap[index[e->pp]].w>heap[index[now]].w+e->ww)
      --> 122: 					up_heap(e->pp,heap[index[now]].w+e->ww);
program.c:134:27: error: invalid types '<unresolved overloaded function type>[int]' for array subscript    temp+=heap[index[cow[j]]].w;                           ^
      --> 133: 		for(j=0;j<N;++j)
      --> 134: 			temp+=heap[index[cow[j]]].w;

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值