acm基本算法.docx
《acm基本算法.docx》由会员分享,可在线阅读,更多相关《acm基本算法.docx(22页珍藏版)》请在冰豆网上搜索。
acm基本算法
#include
//图论
//广度优先搜索
structArc{
intnext_arc;
intpoint;
}arc[1000];
intnode[100];
intque[100];//数组模拟队列
intvis[100];//标志数组,vis[i]=1,表示i已入队,0为未入队
intfront,rear;//队首,队尾指针
voidbfs()
{
front=rear=0;
memset(vis,0,sizeof(int));
que[rear++]=0;//假定从零开始
vis[0]=1;
while(front{
intcur_node=que[front++];
intedg;
for(edg=node[cur_node];edg!
=-1;edg=arc[edg].next_arc)
{
if(!
vis[arc[edg].point])
{
que[rear++]=arc[edg].point;
vis[arc[edg].point]=1;
}
}
}
}
//深度优先搜索
voiddfs(intv)
{
vis[v]=1;
intedg;
for(edg=node[v];edg!
=-1;edg=arc[edg].next_arc)
{
if(!
vis[arc[edg].point])
{
dfs(arc[edg].point);
}
}
}
//拓扑排序
intN,de[1000],top[100],tail,front;
queueq;
intl;
inttop_sort()
{
for(inti=1;i<=N;++i)
{
if(!
de[i])
q.push(i);
}
while(q.empty())
{
intx=q.front();
top[l++]=x;
q.pop();
for(inte=node[x];e!
=-1;e=arc[e].next_arc)
{
de[arc[e].point]--;
if(!
de[arc[e].point])
q.push(arc[e].point);
}
}
returnl;
}
//最小生成树prim
intprim(intcost[][],intn)
{
intlow[10000],vis[1000]={0};
inti,j,p;
intmin,res=0;
vis[0]=1;
for(i=1;ifor(i=1;i,n;i++)
{
min=inf;p=-1;
for(j=0;jif(0==vis[j]&&min>low[j])
{
min=low[j];
p=j;
}
}
if(min==inf)
return-1;
res+=min;
vis[p]=1;
for(j=0;j{
if(0==vis[j]&&low[j]>cost[p][j])
{
low[j]=cost[p][j];
}
}
returnres;
}
//'最小生成树Kruskal
intp[10000];//表示集合数组
intr[10000];
intfind(intv)
{
if(v!
=p[v])
p[v]=find(p[v]);
returnp[v];
}
voidjoin(intu,intv)
{
inta=find(u);
intb=find(v);
if(a==b)return;
if(r[a]{
p[a]=b;
}
elseif(r[a]>r[b])
{
p[b]=a;
}
else{
p[a]=b;
r[b]++;
}
}
voidinit_set(intn)
{
inti;
for(i=1;i<=n;i++)
{
p[i]=i;
r[i]=1;
}
}
structEdge{
intu,v,weight;
}edge[500005];
voidquick_sort(structEdge*start,structEdge*end)
{
if(start>=end)return;
structEdge*loc=start;
structEdge*iterator;
structEdgetmp;
for(iterator=start;iterator!
=end;iterator++)
{
if(iterator->weight<(end-1)->weight)
{
tmp=*loc;
*loc=*iterator;
*iterator=tmp;
loc++;
}
}
tmp=*loc;
*loc=*(end-1);
*(end-1)=tmp;
quick_sort(start,loc);
quick_sort(loc+1,end);
}
intkruskal(intn,intm)
{
intset(n);
quick_sort(edge,edge+m);
inti;
intret=0;
intcnt=0;
for(i=0;i{
intu=edge[i].u;
intv=edge[i].v;
if(find(u)!
=find(v))
{
cnt++;
ret+=edge[i].weight;
join(u,v);
}
if(cnt==n-1)returnret;
}
return-1;
}
//最短路径Dijkstra(邻接矩阵实现)
#defineinf0xfffffff
#definesize150
inta[size][size];
intlow[size];
voiddijkstra(intn)
{
inti,j,k;
low[0]=0;
boolflag[size]={0};
flag[0]=1;
for(i=1;i{
low[i]=a[0][i];
}
for(i=0;i{
intmin=inf;
for(j=0;j{
if(flag[j]==0&&min>low[j])
{
min=low[j];
k=j;
}
}
flag[k]=1;
for(j=0;j{
if(flag[j]==0;a[k][j]+low[k]low[j]=low[k]+a[k][j];
}
}
}
//最短路径dijkstra(邻接表实现)
structArc{
intnext_arc;
intpoint;
intweight;
}arc[M];
intnode[M];
voidinsert_edge(intu,intv,intweight,intedge_num)
{
arc[edge_num].next_arc=node[u];
arc[edge_num].point=v;
arc[edge_num].weight=weight;
node[u]=edge_num;
}
//堆元素结构
structheap_elm{
intnum;
intdis;
}heap[M];
voidinsert(structheap_elmh,int*len)
{
(*len)++;
heap[*len]=h;
inti=*len;
while(i>0)
{
intj=(i>>1);
if(heap[j].dis>heap[i].dis)
{
structheap_elmtmp=heap[j];
heap[j]=heap[i];
heap[i]=tmp;
i=j;
}
elsebreak;
}
}
voidheapfi(intloc,intlen)
{
intleft=(loc<<1);
intright=left+1;
intmin_loc=loc;
if(left<=len&&heap[left].dis{
min_loc=left;
}
if(right<=len&&heap[right].dis{
min_loc=right;
}
if(min_loc!
=loc)
{
structheap_elmtmp=heap[min_loc];
heap[min_loc]=heap[loc];
heap[loc]=tmp;
heapfi(min_loc,len);
}
}
structheap_elmgettop()
{
returnheap[1];
}
voiddel(int*len)
{
heap[1]=heap[*len];
(*len)--;
heapfi(1,*len);
}
intvis[N];
intres[N];
voiddijk(intn,intm,intsrc)
{
memset(vis,0,sizeof(int));
intlen=0;
structheap_elmh;
h.dis=0;
h.num=src;
insert(h,&len);
while(len>0)
{
h=gettop();
del(&len);
if(vis[h.num])continue;
res[h.num]=h.dis;
vis[h.num]=1;
intedge;
for(edge=node[h.num];edge!
=-1;edge=arc[edge].next_arc)
{
if(!
vis[arc[edge].point])
{
structheap_elmt;
t.dis=h.dis+arc[edge].weight;
t.num=arc[edge].point;
insert(t,&len);
}
}
}
}
//最短路径Bellman-ford(邻接矩阵实现)
intres[N];//源点到每个顶点的距离
intg[N][N];
voidbellman(intn,intsrc)
{
memset(res,0x1f,sizeof(int));
res[src]=0;
inti,j,k;
for(i=1;i{
for(j=1;j{
for(k=1;k{
if(res[k]>res[j]+g[j][k])
{
res[k]=res[j]+g[j][k];
}
}
}
}
}
//存储图的边ford:
intres[N];
structEdge{
intv,u,t}edge[E];
boolbellman(intn,intm,intsrc)//n点数,m边数,src为源点
{
memset(res,0x1f,sizeof(int));
res[src]=0;
inti,j,k;
for(i=0;i{
for(j=0;jif(res[edge[j].u]+edge[j].t{
res[edge[j].v]=res[edge[j].u]+edge[j].t;
}
}
for(inti=0;ifor(intj=0;j{
if(res[edge[j].u]+edge[j].treturn1;
}
return0;
}
//SPFA算法;
intres[N];
intg[N][N];
intcnt[N];//每个点入队次数,判断是否出现负环用
intque[N];
boolin_que[N];
inttail;
intfront;
voidspfa(intn,intsrc)
{
tail=front=0;
que[++tail]=src;
memset(res,0x1f,sizeof(int));
memset(in_que,o,sizeof(bool));
res[src]=0;
while(front{
intcur=que[++front];
in_que[cur]=0;
inti;
for(i=1;i{
if(res[cur]+g[cur][i]{
res[i]=res[cur]+g[cur][i];
if(!
in_que[i])
{
que[++tail]=i;
}
}
}
}
}
#include
#include
usingnamespacestd;
inlineintcompare(stringstr1,stringstr2)
{
if(str1.size()>str2.size())//长度长的整数大于长度小的整数
return1;
elseif(str1.size()return-1;
else
returnpare(str2);//若长度相等,从头到尾按位比较,compare函数:
相等返回0,大于返回1,小于返回-1
}
stringADD_INT(stringstr1,stringstr2)
{
stringMINUS_INT(stringstr1,stringstr2);
intsign=1;//sign为符号位
stringstr;
if(str1[0]=='-'){
if(str2[0]=='-'){
sign=-1;
str=ADD_INT(str1.erase(0,1),str2.erase(0,1));
}else{
str=MINUS_INT(str2,str1.erase(0,1));
}
}else{
if(str2[0]=='-')
str=MINUS_INT(str1,str2.erase(0,1));
else{
//把两个整数对齐,短整数前面加0补齐
string:
:
size_typel1,l2;
inti;
l1=str1.size();l2=str2.size();
if(l1for(i=1;i<=l2-l1;i++)
str1="0"+str1;
}else{
for(i=1;i<=l1-l2;i++)
str2="0"+str2;
}
intint1=0,int2=0;//int2记录进位
for(i=str1.size()-1;i>=0;i--){
int1=(int(str1[i])-48+int(str2[i])-48+int2)%10;//48为'0'的ASCII码
int2=(int(str1[i])-48+int(str2[i])-48+int2)/10;
str=char(int1+48)+str;
}
if(int2!
=0)str=char(int2+48)+str;
}
}
//运算后处理符号位
if((sign==-1)&&(str[0]!
='0'))
str="-"+str;
returnstr;
}
//高精度减法
stringMINUS_INT(stringstr1,stringstr2)
{
stringMULTIPLY_INT(stringstr1,stringstr2);
intsign=1;//sign为符号位
stringstr;
if(str2[0]=='-')
str=ADD_INT(str1,str2.erase(0,1));
else{
intres=compare(str1,str2);
if(res==0)return"0";
if(res<0){
sign=-1;
stringtemp=str1;
str1=str2;
str2=temp;
}
string:
:
size_typetempint;
tempint=str1.size()-str2.size();
for(inti=str2.size()-1;i>=0;i--){
if(str1[i+tempint]str1[i+tempint-1]=char(int(str1[i+tempint-1])-1);
str=char(str1[i+tempint]-str2[i]+58)+str;
}
else
str=char(str1[i+tempint]-str2[i]+48)+str;
}
for(inti=tempint-1;i>=0;i--)
str=str1[i]+str;
}
//去除结果中多余的前导0
str.erase(0,str.find_first_not_of('0'));
if(str.empty())str="0";
if((sign==-1)&&(str[0]!
='0'))
str="-"+str;
returnstr;
}
//高精度乘法
stringMULTIPLY_INT(stringstr1,stringstr2)
{
intsign=1;//sign为符号位
stringstr;
if(str1[0]=='-'){
sign*=-1;
str1=str1.erase(0,1);
}
if(str2[0]=='-'){
sign*=-1;
str2=str2.erase(0,1);
}
inti,j;
string:
:
size_typel1,l2;
l1=str1.size();l2=str2.size();
for(i=l2-1;i>=0;i--){//实现手工乘法
stringtempstr;
intint1=0,int2=0,int3=int(str2[i])-48;
if(int3!
=0){
for(j=1;j<=(int)(l2-1-i);j++)
tempstr="0"+tempstr;
for(j=l1-1;j>=0;j--){
int1=(int3*(int(str1[j])-48)+int2)%10;
int2=(int3*(int(str1[j])-48)+int2)/10;
tempstr=char(int1+48)+tempstr;
}
if(int2!
=0)tempstr=char(int2+48)+tempstr;
}
str=ADD_INT(str,tempstr);
}
//去除结果中的前导0
str.erase(0,str.find_first_not_of('0'));
if(str.empty())str="0";
if((sign==-1)&&(str[0]!
='0'))
str="-"+str;
returnstr;
}
//高精度除法
stringDIVIDE_INT(stringstr1,stringstr2,intflag)
{
//flag=1时,返回商;flag=0时,返回余数
stringquotient,residue;//定义商和余数
intsign1=1,sign2=1;
if(str2=="0"){//判断除数是否为0
quotient="ERROR!
";
residue="ERROR!
";
if(flag==1)returnquotient;
elsereturnresidue;
}
if(str1=="0"){//判断被除数是否为0
quotient="0";
residue="0";
}
if(str1[0]=='-'){
str1=str1.erase(0,1);
sign1*=-1;
sign2=-1;
}
if(str2[0]=='-'){
str2=str2.erase(0,1);
sign1*=-1;
}
intres=compare(str1,str2);
if(res<0){
quotient="0";
residue=str1;
}elseif(res==0){
quotient="1";
residue="0";
}else{
string:
:
size_typel1,l2;
l1=str1.size();l2=str2.size();
stringtempstr;
tempstr.append(str1,0,l2-1);
//模拟手工除法
for(inti=l2-1;itempstr=tempstr+str1[i];
fo