Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
这题输入卡了我很久……额……//一直觉得好题应该是不卡输入而是卡算法的。。 //输入好麻烦,各种碎碎念。。 //这个输入应该还算简单吧……其实我对scanf的用法还是不大理解。 //下面是我的代码,链式前向星,Tarjan-LCA,516ms #include <stdio.h> #include <string.h> #define MAXN 4000 #define MAXQ 500000 struct Edge{ int to,next; }; int n,head[MAXN],qhead[MAXN],deg[MAXN],p[MAXN]; //deg[i]先开始表示顶点i的入度,后来表示顶点i作为LCA出现的次数 Edge edge[MAXN],qedge[MAXQ<<1]; bool visit[MAXN]; int find(int x){ if (p[x]!=x) p[x]=find(p[x]); return p[x]; } void LCA(int u) { p[u]=u; int k; for (k=head[u]; k!=-1; k=edge[k].next) if (!visit[ edge[k].to ]) { LCA( edge[k].to ); p[ edge[k].to ] = u; } visit[u] = true; for (k=qhead[u]; k!=-1; k=qedge[k].next) if (visit[ qedge[k].to ]) deg[ find(qedge[k].to) ]++; } int main() { int i,j,k,s,e,q,q1,q2,tot=0,root=-1; while ( scanf("%d",&n)!=EOF ) { memset(head,-1,sizeof(head)); //读入树的信息 memset(deg,0,sizeof(deg)); for (i=0;i<n;i++) { scanf("%d:(%d)", &s, &k); for (j=0;j<k;j++) { scanf("%d", &e); deg[e]++; edge[tot].to = e; edge[tot].next = head[s]; head[s]=tot++; } } scanf("%d",&q); //读入q次询问 for (root=1; deg[root]; root++); //找到树根 memset(qhead,-1,sizeof(qhead)); memset(deg,0,sizeof(deg)); memset(visit,false,sizeof(visit)); for (tot=i=0;i<q;i++) { scanf(" (%d %d) ", &q1, &q2); if (q1==q2) {++deg[q1]; continue;} qedge[tot].to = q2; //所有的边存两遍,但只对其中一次做出应答 qedge[tot].next = qhead[q1]; qhead[q1] = tot++; qedge[tot].to = q1; qedge[tot].next = qhead[q2]; qhead[q2] = tot++; } LCA(root); for (i=1;i<=n;i++) if (deg[i]) printf("%d:%d\n", i, deg[i]); } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator