| ||||||||||
| 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