hdu 6074 Phone Call
题
O∧O http://acm.hdu.edu.cn/showproblem.php?pid=6074
2017 Multi-University Training Contest - Team 4 - 1008
解
fread真是其乐无穷呀!
对于每个给出的ai,bi,ci,di,wi,记ai,bi的LCA为pi, 记ci,di的LCA为qi,
首先根据wi来排序这些电话线
使用并查集
首先把ai到pi路径上未加入pi集合的点加入pi集合,然后把bi到pi路径上未加入pi集合的点加入pi集合,
同样地,把ci到qi路径上未加入qi集合的点加入qi集合,di到qi路径上未加入qi集合的点加入qi集合。
然后把如果qi未加入pi集合,那么把qi加入pi集合
然后向上搜未加入集合点的时候,是可以跳跃着做的。
这种代码,写一会想玩会手机。O∧O
624ms代码
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; namespace fastIO { #define BUF_SIZE 100000 //fread -> read bool IOerror = 0; inline char nc() { static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE; if(p1 == pend) { p1 = buf; pend = buf + fread(buf, 1, BUF_SIZE, stdin); if(pend == p1) { IOerror = 1; return -1; } } return *p1++; } inline bool blank(char ch) { return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'; } inline void read(int &x) { char ch; while(blank(ch = nc())); if(IOerror) return; for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0'); } #undef BUF_SIZE }; using namespace fastIO; typedef long long ll; const int MAXN = 100010; const int MAXQ = 200010;//查询数的最大值 //并查集部分 int F[MAXN];//需要初始化为-1 int find(int x) { if(F[x] == -1)return x; return F[x] = find(F[x]); } void bing(int u,int v) { int t1 = find(u); int t2 = find(v); if(t1 != t2) F[t1] = t2; } bool vis[MAXN];//访问标记 int ancestor[MAXN];//祖先 struct Edge { int to,next; }edge[MAXN*2]; int head[MAXN],tot; void addedge(int u,int v) { edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; } struct Query { int q,next; int index;//查询编号 }query[MAXQ*2]; int answer[MAXQ];//存储最后的查询结果,下标0~Q-1 int h[MAXQ]; int tt; int Q; void add_query(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; 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,false,sizeof(vis)); memset(F,-1,sizeof(F)); memset(ancestor,0,sizeof(ancestor)); } void LCA(int u) { ancestor[u] = u; vis[u] = true; for(int i = head[u];i != -1;i = edge[i].next) { int v = edge[i].to; if(vis[v])continue; LCA(v); bing(u,v); ancestor[find(u)] = u; } for(int i = h[u];i != -1;i = query[i].next) { int v = query[i].q; if(vis[v]) { answer[query[i].index] = ancestor[find(v)]; } } } const int M=100044; struct PhoneLine { int a,b,c,d,w,id; } pl[M]; int n,m; int fa[M],ansnum,jmp[M],num[M]; int stk[M],lstk,dep[M]; ll cst[M],anscst; bool cmp(PhoneLine x,PhoneLine y) { return x.w<y.w; } void getjmp(int rt,int pa,int depth) { dep[rt]=depth; int i,j,v; jmp[rt]=pa; for(i=head[rt];i!=-1;i=edge[i].next) { v=edge[i].to; if(v==pa) continue; getjmp(v,rt,depth+1); } } void init2() { int i,j; for(i=1;i<=n;i++) { fa[i]=i; num[i]=1; cst[i]=0; } ansnum=0; anscst=0; getjmp(1,0,1); } int fff(int x) { if(fa[x]==x) return x; fa[x]=fff(fa[x]); return fa[x]; } void merge(int a,int t,int w) { int i,j,pa,pt,tmp; while(dep[a]>dep[t]) { tmp=jmp[a]; jmp[a]=jmp[t]; pa=fff(a); pt=fff(t); if(pa!=pt) { fa[pa]=pt; num[pt]+=num[pa]; cst[pt]+=cst[pa]+w; } a=tmp; } } void solve() { int i,j,a,b,w,pa,pb,t,tmp; for(i=0;i<m;i++) { w=pl[i].w; t=answer[i*2]; a=pl[i].a; b=pl[i].b; merge(a,t,w); merge(b,t,w); t=answer[i*2+1]; a=pl[i].c; b=pl[i].d; merge(a,t,w); merge(b,t,w); a=answer[i*2]; b=answer[i*2+1]; pa=fff(a); pb=fff(b); if(pa!=pb) { fa[pa]=pb; num[pb]+=num[pa]; cst[pb]+=cst[pa]+w; } } } int main() { // freopen("数据\\1008.in","r",stdin); // freopen("数据\\1008my.out","w",stdout); int i,j,u,v; int cas; read(cas); while(cas--) { init(); read(n); read(m); for(i=1;i<n;i++) { read(u); read(v); addedge(u,v); addedge(v,u); } for(i=0;i<m;i++) { pl[i].id=i; read(pl[i].a); read(pl[i].b); read(pl[i].c); read(pl[i].d); read(pl[i].w); } sort(pl,pl+m,cmp); Q=2*m; for(i=0;i<m;i++) { add_query(pl[i].a,pl[i].b,i*2); add_query(pl[i].c,pl[i].d,i*2+1); } LCA(1); // printf("LCA finished\n"); init2(); solve(); for(i=1;i<=n;i++) if(num[i]>ansnum) { ansnum=num[i]; anscst=cst[i]; } printf("%d %lld\n",ansnum,anscst); } return 0; }