hdu2874Connections between cities【LCA tarjan】
来源:互联网 发布:屏幕下指纹识别 知乎 编辑:程序博客网 时间:2024/06/08 06:01
LCA比较基础的题,而且貌似自己的代码只是MLE而已,结果没问题 ,而且也只是超了一点~
mark一下别人过的
#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;}
对比我忧伤的代码156635002015-11-27 12:15:27Memory Limit Exceeded2874655MS33416K3751 BC++20130738156634912015-11-27 12:14:18Memory Limit Exceeded2874405MS33412K3751 BC++20130738156634802015-11-27 12:12:29Memory Limit Exceeded2874670MS33216K3751 BG++20130738156634762015-11-27 12:11:55Memory Limit Exceeded2874686MS33216K3807 BG++20130738
/********hdu28742015.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;}
0 0
- hdu2874Connections between cities【LCA tarjan】
- hdu2874-Connections between cities (LCA/离线tarjan)
- HDU2874 Connections between cities(tarjan-lca)
- hdu2874_Connections between cities(tarjan/lca/边表)
- hdoj 2874 Connections between cities 【Tarjan离线LCA】
- HDU 2874 - Connections between cities(LCA‘离线算法Tarjan)
- HDU 2874 Connections between cities(LCA Tarjan)
- hdu2874 Connections between cities--LCA
- HDU2874 Connections between cities【LCA】
- hdu2874 Connections between cities(LCA)
- hdu 2874 Connections between cities 最近公共祖先lca(离线算法/tarjan算法)
- HDU 2874 Connections between cities LCA Tarjan 链式前向星
- hdu 2874 Connections between cities LCA
- HDU 2874 Connections between cities [LCA]
- hdu 2874 Connections between cities (LCA)
- hdu 2874 Connections between cities(LCA)
- 【HDU】2874 Connections between cities 离线LCA
- hdu 2874 Connections between cities(LCA)
- Android RecyclerView的使用
- Android总结篇系列:Android广播机制
- 解析路飞惊人战斗力由何而来
- vim添加中文帮助文档
- [Javascript] variable, scope, scope chain, execution context
- hdu2874Connections between cities【LCA tarjan】
- 8天学通MongoDB——第二天 细说增删查改
- JPA:继承
- KnockoutJS Documentation-加载和保存json数据
- ubuntu必要软件及其命令
- Uva 10410 层序+前序构造树
- SAP系统内部顾问如何培养
- static(静态)变量的作用、初始化特点以及类中静态数据成员的特点
- 关于浏览器window、document、html、body高度的探究