O(n*n)贪心算法实现杭电-1025

使用贪心算法

基本思想:

  1.对线路按rich city的序号排序 O(n*lgn);

       2.计算每条线路与其它线路的交点,多条线路交与同一点算多点而非一点O(n*2);

       3.从线路集合中寻找交点最多的线路,如果它的交点数不为0,转4,否则,退出,输出当前剩余的线路数;

       4.更新每条与该 交点最多的线路相交的线路的交点数(-1), 从线路集合中去掉该交点最多的线路,转3;

 该算法,可以结束,3,4步最多执行n次,并且3,4步的复杂服最差为O(n*2),可惜超时。

#include <stdio.h>
#include
<malloc.h>
#include
<cstring>
typedef
struct
{
int d[3];
}Road;

Road
*rs;

void SwapDepth(Road rs[],int s,int e,int dim)
{
int maxindex;
int c=s;
Road temp;
while(c<e)
{
maxindex
=c;
if(2*c+2<e && rs[maxindex].d[dim]<rs[2*c+2].d[dim])
maxindex
=2*c+2;
if(2*c+1<e && rs[maxindex].d[dim]<rs[2*c+1].d[dim])
maxindex
=2*c+1;
if(maxindex != c)
{
temp
= rs[c];
rs[c]
= rs[maxindex];
rs[maxindex]
= temp;
c
=maxindex;
}
else
break;
}
}

void CreateHeap(Road rs[],int n,int dim)
{
for(int i=n/2-1;i>=0;--i)
SwapDepth(rs,i,n,dim);
}

void IncreaseHeap(Road rs[],int n,int dim,int index,int incValue)
{
int p=index/2-1;
Road temp;
while(p>=0)
{
if(rs[p].d[dim]<rs[index].d[dim]+incValue)
rs[index].d[dim]
+=incValue;
temp
=rs[p];
rs[p]
=rs[index];
rs[index]
=temp;
index
=p;
p
=index/2-1;
}
}

void DecreaseHeap(Road rs[],int n,int dim,int index,int decValue)
{
rs[index].d[dim]
-= decValue;
SwapDepth(rs,index,n,dim);
}

void SortHeap(Road rs[],int n,int dim)
{
CreateHeap(rs,n,dim);
Road temp;
for(int i=n-1;i>0;--i)
{
temp
= rs[0];
rs[
0] = rs[i];
rs[i]
= temp;
SwapDepth(rs,
0,i,dim);
}
}

int MaximalRoads(Road rs[],int n)
{
Road temp;
SortHeap(rs,n,
0);
//寻找每条路的与之相交的路线数目rs[i].d[2]
for(int i=1;i<n;++i)
{
for(int j=i-1;j>=0;--j)
if(rs[j].d[1]>rs[i].d[1])
{
++rs[j].d[2];
++rs[i].d[2];
}
}
CreateHeap(rs,n,
2);
int length=n;
while(length>0 && rs[0].d[2]>0)
{
for(int i=1;i<length;++i)
{
if((rs[0].d[0]-rs[i].d[0])*(rs[0].d[1]-rs[i].d[1])<0)
{
--rs[i].d[2];
}
}
temp
=rs[0];
rs[
0]=rs[length-1];
rs[length
-1]=temp;
--length;
CreateHeap(rs,length,
2);
SwapDepth(rs,
0,length-1,2);
}
return length;
}

void ReadData()
{
int n;
int j=0;
while(scanf("%d",&n)==1 && n)
{
rs
= (Road *)malloc(n*sizeof(Road));
if(rs)
{
for(int i=0;i<n;++i)
{
scanf(
"%d %d",(rs+i)->d,(rs+i)->d+1);
((rs
+i)->d)[2]=0;
}
int roadsnum=MaximalRoads(rs,n);
if (roadsnum==1)
printf(
"Case %d:\nMy king, at most %d road can be built.\n\n",++j,roadsnum);
else
printf(
"Case %d:\nMy king, at most %d roads can be built.\n\n",++j,roadsnum);

free(rs);
rs
=NULL;
}
}
}

int main()
{
ReadData();
return 0;
}

posted on 2011-05-10 15:45  明日之星  阅读(241)  评论(0)    收藏  举报