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;
}
浙公网安备 33010602011771号