LCA比较基础的题,而且貌似自己的代码只是MLE而已,结果没问题 ,而且也只是超了一点~
mark一下别人过的
2168MS | 21700K | 2458B |
#include <cstdio> #include <algorithm> #include <string> #include <cstring> #include <stack> #include <cmath> #include <queue> #include <list> #include <cstdlib> #include <vector> #include <set> #include <map> #include <sstream> #include <iostream> #include <stack> using namespace std; int n,m,q; struct Node { int e,xia,val; }e1[20001]; struct Node2 { int e,xia; }e2[2000001]; int d1,d2,head1[10001],head2[10001]; bool vis[10001]; int fat[10001],dis[10001],ans[1000001];//所有答案记录在ans数组里。 void add1(int s,int e,int val) { e1[d1].e=e,e1[d1].val=val,e1[d1].xia=head1[s]; head1[s]=d1++; } void add2(int s,int e) { e2[d2].e=e,e2[d2].xia=head2[s]; head2[s]=d2++; } int find(int num) { if(fat[num] == num)return num; return fat[num]=find(fat[num]); } void Union(int s,int e) { fat[e]=s; } void tarjan(int s) { int i; vis[s]=true; fat[s]=s; for(i=head1[s];i != -1;i=e1[i].xia) { if(!vis[e1[i].e]) { dis[e1[i].e]=dis[s]+e1[i].val; tarjan(e1[i].e); Union(s,e1[i].e); } } for(i=head2[s];i != -1 ;i=e2[i].xia) { if(vis[e2[i].e]) { if(dis[e2[i].e] != -1) { ans[i/2]=dis[s]+dis[e2[i].e]-2*dis[find(e2[i].e)]; } else ans[i/2]=-1; } } } int main() { int i,j,ji1,ji2,ji3; while(~scanf("%d %d %d",&n,&m,&q)) { d1=d2=0; memset(head1,-1,sizeof(head1)); memset(head2,-1,sizeof(head2)); for(i=0;i<m;i++) { scanf("%d %d %d",&ji1,&ji2,&ji3); add1(ji1,ji2,ji3); ji1^=ji2,ji2^=ji1,ji1^=ji2; add1(ji1,ji2,ji3); } for(i=0;i<q;i++) { scanf("%d %d",&ji1,&ji2); add2(ji1,ji2); ji1^=ji2,ji2^=ji1,ji1^=ji2; add2(ji1,ji2); } memset(vis,false,sizeof(vis)); for(i=1;i<=n;i++)fat[i]=i; for(i=1;i<=n;i++) { if(!vis[i]) { memset(dis,-1,sizeof(dis)); dis[i]=0; tarjan(i); } } for(i=0;i<q;i++) { if(ans[i] == -1)puts("Not connected"); else printf("%d\n",ans[i]); } } return 0; }
15663500 | 2015-11-27 12:15:27 | Memory Limit Exceeded | 2874 | 655MS | 33416K | 3751 B | C++ | 20130738 |
15663491 | 2015-11-27 12:14:18 | Memory Limit Exceeded | 2874 | 405MS | 33412K | 3751 B | C++ | 20130738 |
15663480 | 2015-11-27 12:12:29 | Memory Limit Exceeded | 2874 | 670MS | 33216K | 3751 B | G++ | 20130738 |
15663476 | 2015-11-27 12:11:55 | Memory Limit Exceeded | 2874 | 686MS | 33216K | 3807 B | G++ | 20130738 |
/******** hdu2874 2015.11.27 ********/ #include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> #pragma warning(disable:4996) using namespace std; const int maxn=10000;//顶点数 const int maxq=1000000;//最多查询次数,根据题目而定. int t; int n,u,v,len,m,c; //并查集 int f[maxn];//根节点 int find(int x) { if(f[x]==x) return x; return f[x]=find(f[x]); } void unite(int u,int v) { int x=find(u); int y=find(v); if(x!=y) f[x]=y; } //并查集结束 bool vis[maxn];//节点是否访问 int ancestor[maxn];//节点i的祖先 struct Edge { int to,next,len; }edge[maxn*2]; int head[maxn],tot; void addedge(int u,int v,int length)//邻接表头插法加边 { edge[tot].to=v; edge[tot].len=length; // printf("%d ",length); edge[tot].next=head[u]; head[u]=tot++; } struct Query { int q,next; int index;//查询编号,也就是输入的顺序 }query[maxq*2]; int ans[maxq];//存储每次查询的结果,下表0~Q-1,其实应该开maxq大小的。 int h[maxq],tt; int Q;//题目中需要查询的次数 int dis[maxn]; void addquery(int u,int v,int index)//邻接表头插法加询问 { query[tt].q=v; query[tt].next=h[u]; query[tt].index=index; h[u]=tt++; query[tt].q=u;//相当于两次查询,比如查询 3,5 和5,3结果是一样的,以3为头节点的邻接表中有5,以5为头节点的邻接表中有3 query[tt].next=h[v]; query[tt].index=index; h[v]=tt++; } void init() { tot=0; memset(head,-1,sizeof(head)); tt=0; memset(h,-1,sizeof(h)); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) f[i]=i; memset(ancestor,0,sizeof(ancestor)); memset(dis,0,sizeof(dis)); memset(ans,0,sizeof(ans)); } void LCA(int u) { ancestor[u]=u; vis[u]=true; for(int i=head[u];i!=-1;i=edge[i].next)//和顶点u相关的顶点 { int v=edge[i].to; // printf("%d ",edge[i].len); if(vis[v]) continue; //dis[v]+=edge[i].len; dis[v]=dis[u]+edge[i].len; LCA(v); unite(u,v); ancestor[find(u)]=u;//将u的左右孩子的祖先设为u //dis[find(u)]+=dis[u]; } for(int i=h[u];i!=-1;i=query[i].next)//看输入的查询里面有没有和u节点相关的 { int v=query[i].q; if(vis[v]) ans[query[i].index]=ancestor[find(v)]; } } bool flag[maxn];//用来确定根节点的 int main() { int a,b,c; freopen("cin.txt","r",stdin); // scanf("%d(%d):%d",&a,&b,&c); // cout<<a<<b<<c; // scanf("%d",&t); while(~scanf("%d%d%d",&n,&m,&c)) { init(); memset(flag,0,sizeof(flag)); for(int i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&len); flag[v]=true;//有入度 addedge(u,v,len); addedge(v,u,len); // unite(u,v); } // for(int i=1;i<=n;i++) printf("i=%d f=%d ",i,f[i]); for(int i=0;i<c;i++) { scanf("%d%d",&u,&v); addquery(u,v,i); } int root; for(int i=1;i<=n;i++) { if(f[i]==i) { root=i; // // printf("root=%d ",root); LCA(root); f[i]=i; //break; } } //for(int i=1;i<=n;i++)printf("%d ",dis[i]); printf("\n"); for(int i=0;i<c;i++) { //if(f[query[i<<1].q]!=f[query[i<<1|1].q]) if(f[query[i<<1].q]!=f[query[i<<1|1].q]) { puts("Not connected"); continue; } len=dis[query[i<<1].q]+dis[query[i<<1|1].q]-dis[ans[i]]*2; printf("%d\n",len); } } return 0; }