NOIP复赛复习6程序对拍与图论模板.docx
《NOIP复赛复习6程序对拍与图论模板.docx》由会员分享,可在线阅读,更多相关《NOIP复赛复习6程序对拍与图论模板.docx(16页珍藏版)》请在冰豆网上搜索。
NOIP复赛复习6程序对拍与图论模板
NOIP复赛复习6程序对拍与图论模板
程序对拍
所谓“对拍”,顾名思义,就是让两者相互比对。
所谓“两者”,一是你要测试的程序,二是一个答案在该程序在一定范围(时间/空间)内结果必定正确的程序(一般是用暴力求解的程序)。
对拍一般需要造数据程序(data.exe),保证正确性的暴力对拍程序(test.exe)与测试程序(以moo.exe为例)。
下面是对拍的代码,写在txt中再转成.bat即可。
:
loop
data.exe
test.exe
moo.exe
fcmoo.outtest.out
if%errorlevel%==0gotoloop
pause
图论算法
1、图的遍历-BFS
#include
#include
#defineN5
usingnamespacestd;
intmaze[N][N]={
{0,1,1,0,0},
{0,0,1,1,0},
{0,1,1,1,0},
{1,0,0,0,0},
{0,0,1,1,0}
};
intvisited[N+1]={0,};
voidBFS(intstart)
{
queueQ;
Q.push(start);
visited[start]=1;
while(!
Q.empty())
{
intfront=Q.front();
cout< Q.pop();
for(inti=1;i<=N;i++)
{
if(!
visited[i]&&maze[front-1][i-1]==1)
{
visited[i]=1;
Q.push(i);
}
}
}
}
intmain()
{
for(inti=1;i<=N;i++)
{
if(visited[i]==1)
continue;
BFS(i);
}
return0;
}
2、图的遍历-DFS
#include
#include
#defineN5
usingnamespacestd;
intmaze[N][N]={
{0,1,1,0,0},
{0,0,1,0,1},
{0,0,1,0,0},
{1,1,0,0,1},
{0,0,1,0,0}
};
intvisited[N+1]={0,};
voidDFS(intstart)
{
stacks;
s.push(start);
visited[start]=1;
boolis_push=false;
while(!
s.empty())
{
is_push=false;
intv=s.top();
for(inti=1;i<=N;i++)
{
if(maze[v-1][i-1]==1&&!
visited[i])
{
visited[i]=1;
s.push(i);
is_push=true;
break;
}
}
if(!
is_push)
{
cout< s.pop();
}
}
}
intmain()
{
for(inti=1;i<=N;i++)
{
if(visited[i]==1)
continue;
DFS(i);
}
return0;
}
3、最小生成树-Kruskal
#include
#include
using namespace std;
const int MAXN = 30;
int pa[MAXN];
int rank[MAXN];
int n,sum;
struct node{
int x,y;
int w;
}edge[MAXN*MAXN];
bool cmp(node p,node q){
return p.w}
void make_set(int x)
{
pa[x] = x;
rank[x] = 0;
}
int find_set(int x)
{
if(x !
= pa[x])
pa[x] = find_set(pa[x]);
return pa[x];
}
void union_set(int x, int y,int w)
{
x = find_set(x);
y = find_set(y);
if(x == y)return ;
if(rank[x] > rank[y])
{
pa[y] = x;
}
else
{
pa[x] = y;
if(rank[x] == rank[y])
rank[y]++;
}
sum+=w;
}
int main()
{
// freopen("input.txt","r",stdin);
while(cin>>n){
if(!
n) break;
char ch;
int m,k=0;
for (int i = 0; i < n - 1; i++)
{
cin >> ch >> m;
for (int j = 0; j < m; j++)
{
cin >> ch >> edge[k].w;
edge[k].x = i;
edge[k].y = ch - 'A';
k++;
}
}
sort(edge,edge+k,cmp);
for(int i=0;i make_set(i);
sum=0;
for(int i=0;i union_set(edge[i].x,edge[i].y,edge[i].w);
cout< }
}
4、最小生成树-Prim
#include
using namespace std;
const int maxn=30;
const int INF=1000000;
int graph[maxn][maxn];
int lowcost[maxn],closet[maxn];
int visited[maxn];
int n;
void createGraph(){
memset(graph,0,sizeof(graph));
memset(lowcost,0,sizeof(lowcost));
memset(closet,0,sizeof(closet));
memset(visited,0,sizeof(visited));
int a;
for(int i=0;i for(int j=0;j scanf("%d",&a);
if(a==0)
graph[i][j]=graph[j][i]=INF;
else
graph[i][j]=graph[j][i]=a;
}
}
void prim(){
int sum=0;
visited[0]=1;
for(int i=0;i lowcost[i]=graph[i][0];
closet[i]=0;
}
for(int i=1;i int minn=lowcost[0],k=0;
for(int j=0;j if(!
visited[j] && lowcost[j] minn=lowcost[j];
k=j;
}
}
sum+=minn;
visited[k]=1;
for(int t=0;t if(!
visited[t] && lowcost[t]>graph[t][k]){
lowcost[t]=graph[t][k];
closet[t]=k;
}
}
}
printf("%d\n",sum);
}
int main()
{
// freopen("input.txt","r",stdin);
while(~scanf("%d",&n)){
if(!
n) break;
createGraph();
prim();
}
}
5、最短路径-SPFA
#include
#include
#include
#include
usingnamespacestd;
constintmaxn=100005;
structdqs
{
intf,t,c;
}hh[maxn];
inttot=0,first[maxn],next[maxn],d[maxn];
boolused[maxn];
voidbuild(intf,intt,intc)
{
hh[++tot]=(dqs){f,t,c};
next[tot]=first[f];
first[f]=tot;
}
queueq;
intn,m,s,e;
voidspfa(ints)
{
d[s]=0;
q.push(s);
used[s]=1;
while(!
q.empty())
{
intx=q.front();
q.pop();
used[x]=0;
for(inti=first[x];i;i=next[i])
{
intu=hh[i].t;
if(d[u]>d[x]+hh[i].c)
{
d[u]=d[x]+hh[i].c;
if(!
used[u])
{
q.push(u);
used[u]=1;
}
}
}
}
}
intmain()
{
scanf("%d%d%d%d",&n,&m,&s,&e);
for(inti=1;i<=n;i++)
d[i]=1e9;
for(inti=1;i<=m;i++)
{
intf,t,c;
scanf("%d%d%d",&f,&t,&c);
build(f,t,c);
build(t,f,c);
}
spfa(s);
printf("%d\n",d[e]);
return0;
}
6、最短路径-Dijkstra
#include
#include
#include
usingnamespacestd;
constintmaxn=100005;
structdqs
{
intf,t,c;
}hh[maxn];
inttot=0,first[maxn],next[maxn],d[maxn];
boolused[maxn];
voidbuild(intf,intt,intc)
{
hh[++tot]=(dqs){f,t,c};
next[tot]=first[f];
first[f]=tot;
}
intn,m,s,e;
voidDijkstra()
{
for(inti=1;i<=n;i++)
d[i]=1e9;
d[s]=0;
while(true)
{
intx=-1;
for(inti=1;i<=n;i++)
{
if(!
used[i])
if(x==-1||d[i] x=i;
if(x==-1)break;
used[x]=1;
for(inti=first[x];i;i=next[i])
{
intu=hh[i].t;
if(d[u]>d[x]+hh[i].c)
d[u]=d[x]+hh[i].c;
}
}
}
}
intmain()
{
scanf("%d%d%d%d",&n,&m,&s,&e);
......
}
7、最短路径-Floyd
#include
#include
#include
usingnamespacestd;
constintmaxn=1005;
intd[maxn][maxn];
intn,m,s,e;
voidfloyd()
{
for(intk=1;k<=n;k++)
for(inti=1;i<=n;i++)
for(intj=1;j<=n;j++)
if(i!
=j&&i!
=k&&k!
=j)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
}
intmain()
{
scanf("%d%d%d%d",&n,&m,&s,&e);
for(inti=1;i<=n;i++)
for(intj=1;j<=n;j++)
d[i][j]=1e9;
for(inti=1;i<=m;i++)
{
intf,t,c;
scanf("%d%d%d",&f,&t,&c);
d[f][t]=c;
d[t][f]=c;
}
floyd();
printf("%d\n",d[s][e]);
return0;
}
8、最近公共祖先(LCA)-倍增
#include
#include
#include
#include
usingnamespacestd;
constintmaxn=250010;
structdqs
{
intf,t,c;
}hh[maxn<<1];
inttot=0,fa[maxn][31],next[maxn],first[maxn],f[maxn],d[maxn];
voidbuild(intff,inttt,intcc)
{
hh[++tot]=(dqs){ff,tt,cc};
next[tot]=first[ff];
first[ff]=tot;
}
intdeep[maxn];
voiddfs(intx,intsd)
{
deep[x]=sd;
intu;
for(inti=first[x];i;i=next[i])
{
u=hh[i].t;
if(!
deep[u]&&u)
{
f[u]=x;
d[u]=d[x]+hh[i].c;
dfs(u,sd+1);
}
}
}
intlca(intx,inty)
{
if(deep[x] swap(x,y);
intdeepcha=deep[x]-deep[y];
for(inti=0;i<=30;i++)
{
if(1<
x=fa[x][i];
}
for(inti=30;i>=0;i--)
{
if(fa[x][i]!
=fa[y][i])
{
x=fa[x][i];
y=fa[y][i];
}
}
if(x!
=y)
returnf[x];
returnx;
}
intmain()
{
intn;
scanf("%d",&n);
intu,v,c;
for(inti=1;i {
scanf("%d%d%d",&u,&v,&c);
build(u,v,c);
build(v,u,c);
}
dfs(0,0);
for(inti=0;i fa[i][0]=f[i];
for(intj=1;j<=20;j++)
for(inti=1;i<=n;i++)
fa[i][j]=fa[fa[i][j-1]][j-1];
intm;
scanf("%d",&m);
for(inti=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
intxx=lca(u,v);
printf("%d\n",d[u]+d[v]-2*d[xx]);
}
return0;
}