因为手残,wa了很多遍。
在tarjra函数中,第一次循环调用的是b数组,我写成了a数组,一直找不到哪儿错了,一直到刚才终于发现了。大概11A的样子?
这道题让我非常头疼的一个问题是MLE,内存就差那么一点儿不够使。我原本的代码存边的时候是同时存起点和终点,为了解决这个问题,我用了short存的起点和终点。后来看了别人的代码才发现还可以不存起点。。。。。。
用short存起点和终点AC的代码,28040K:
#include<stdio.h>
#include<string.h>
#define N 10005
#define M 1000005
struct node
{
short to,next;
int data;
}a[N*2];
struct point
{
short from,to;
int next;
int data;
}b[M*2];
int LCA[M],head[N],head1[N],vis[N],dis[N],father[N],id[N];
int n,m,c;
int tol,toll,tt;
void add(int x,int y,int k)
{
a[tol].to=y;a[tol].data=k;a[tol].next=head[x];head[x]=tol++;
return ;
}
void add1(int x,int y,int k)
{
b[toll].from=x;b[toll].to=y;b[toll].data=k;b[toll].next=head1[x];head1[x]=toll++;
return ;
}
int Find(int x)
{
while(x!=father[x])
x=father[x];
return x;
}
void tarjan(int u)
{
int v;
vis[u]=1;
father[u]=u;
id[u]=tt;
for(int j=head1[u];j!=-1;j=b[j].next)
{
v=b[j].to;
if(vis[v]&&id[u]==id[v])
LCA[b[j].data]=Find(v);
}
for(int j=head[u];j!=-1;j=a[j].next)
{
v=a[j].to;
if(!vis[v])
{
dis[v]=dis[u]+a[j].data;
tarjan(v);
father[v]=u;
}
}
return ;
}
int main()
{
while(scanf("%d%d%d",&n,&m,&c)!=EOF)
{
memset(head,-1,sizeof(head));
tol=0;
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
memset(head1,-1,sizeof(head1));
toll=0;
for(int i=1;i<=c;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add1(x,y,i);
add1(y,x,i);
}
memset(LCA,-1,sizeof(LCA));
memset(vis,0,sizeof(vis));
memset(id,0,sizeof(id));
tt=1;
for(int i=1;i<=n;i++,tt++)
{
if(!vis[i])
{
dis[i]=0;
tarjan(i);
}
}
for(int j=0;j<toll;j+=2)
{
int x,y,z;
x=b[j].from;
y=b[j].to;
z=b[j].data;
if(LCA[z]!=-1)
printf("%d\n",dis[x]+dis[y]-2*dis[LCA[z]]);
else
printf("Not connected\n");
}
}
return 0;
}
加边的时候不记起点,32036K:
#include<stdio.h>
#include<string.h>
#define N 10005
#define M 1000005
struct node
{
int to;
int next;
int data;
}a[N*2],b[M*2];
int LCA[M],head[N],head1[N],vis[N],dis[N],father[N],id[N],ans[M];
int n,m,c;
int tol,toll,tt;
void add(int x,int y,int k)
{
a[tol].to=y;a[tol].data=k;a[tol].next=head[x];head[x]=tol++;
return ;
}
void add1(int x,int y,int k)
{
b[toll].to=y;b[toll].data=k;b[toll].next=head1[x];head1[x]=toll++;
return ;
}
int Find(int x)
{
while(x!=father[x])
x=father[x];
return x;
}
void tarjan(int u)
{
int v;
vis[u]=1;
father[u]=u;
id[u]=tt;
for(int j=head1[u];j!=-1;j=b[j].next)
{
v=b[j].to;
if(vis[v]&&id[u]==id[v])
{
LCA[b[j].data]=Find(v);
ans[b[j].data]=dis[v]+dis[u]-2*dis[LCA[b[j].data]];
}
}
for(int j=head[u];j!=-1;j=a[j].next)
{
v=a[j].to;
if(!vis[v])
{
dis[v]=dis[u]+a[j].data;
tarjan(v);
father[v]=u;
}
}
return ;
}
int main()
{
while(scanf("%d%d%d",&n,&m,&c)!=EOF)
{
memset(head,-1,sizeof(head));
tol=0;
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
memset(head1,-1,sizeof(head1));
toll=0;
for(int i=1;i<=c;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add1(x,y,i);
add1(y,x,i);
}
memset(LCA,-1,sizeof(LCA));
memset(vis,0,sizeof(vis));
memset(id,0,sizeof(id));
memset(ans,-1,sizeof(ans));
tt=1;
for(int i=1;i<=n;i++,tt++)
{
if(!vis[i])
{
dis[i]=0;
tarjan(i);
}
}
for(int j=0;j<toll;j+=2)
{
int x;
x=b[j].data;
if(LCA[x]!=-1)
printf("%d\n",ans[x]);
else
printf("Not connected\n");
}
}
return 0;
}