[HDU6074] Phone Call
来源:互联网 发布:关机准备配置windows 编辑:程序博客网 时间:2024/06/05 17:39
Problem Link
Description
给定一棵有
Solution
很容易看出来这是一道类似于最小生成树的题目,我们只要将集合按照
Code
#include<stdio.h>#include<string.h>#include<algorithm>#include<iostream>#define M 100005#define ll long longusing namespace std;template <class T>inline void Rd(T &res){ char c;res=0;int k=1; while(c=getchar(),c<48&&c!='-'); if(c=='-'){k=-1;c='0';} do{ res=(res<<3)+(res<<1)+(c^48); }while(c=getchar(),c>=48); res*=k;}template <class T>inline void Pt(T res){ if(res<0){ putchar('-'); res=-res; } if(res>=10)Pt(res/10); putchar(res%10+48);}struct edge{ int v,nxt;}e[M<<1];struct node{ int a,b,c,d,w; bool operator <(const node &tmp)const{ return w<tmp.w; }}s[M];void swap(int &a,int &b){ int t=a;a=b;b=t;}int T;int n,m;int fa[M],sum[M];ll cost[M];int pa[M],dep[M],top[M],son[M],sz[M];int head[M],nxt[M],cnt;void add_edge(int u,int v){ e[++cnt].v=v;e[cnt].nxt=head[u];head[u]=cnt;}void dfs(int x,int t){ nxt[x]=pa[x]=t; sz[x]=1; if(~t)dep[x]=dep[t]+1; for(int i=head[x];~i;i=e[i].nxt){ int v=e[i].v; if(v==t)continue; dfs(v,x); sz[x]+=sz[v]; if(sz[son[x]]<sz[v])son[x]=v; }}void rdfs(int x,int t,int tp){ top[x]=tp; for(int i=head[x];~i;i=e[i].nxt){ int v=e[i].v; if(v==t)continue; if(v==son[x])rdfs(v,x,tp); else rdfs(v,x,v); }}int LCA(int u,int v){ while(top[u]!=top[v]){ if(dep[top[u]]>dep[top[v]])u=pa[top[u]]; else v=pa[top[v]]; } return dep[u]<dep[v]?u:v;}int getfa(int v){ if(fa[v]==v)return v; return fa[v]=getfa(fa[v]);}bool same(int x,int y){ return getfa(x)==getfa(y);}void merge(int x,int y,int w){//把dep大的并到dep小的上 int px=getfa(x); int py=getfa(y); if(dep[px]>dep[py])swap(px,py); sum[px]+=sum[py]; fa[py]=px; cost[px]+=cost[py]+w;}void calc(int u,int v,int w,int lca){ while(~u&&dep[u]>dep[lca]){ if(!same(u,lca))merge(lca,u,w); int tmp=nxt[u]; nxt[u]=pa[lca]; u=tmp; } while(~v&&dep[v]>dep[lca]){ if(!same(v,lca))merge(lca,v,w); int tmp=nxt[v]; nxt[v]=pa[lca]; v=tmp; }}void solve(int a,int b,int c,int d,int w){ int x=LCA(a,b),y=LCA(c,d); calc(a,b,w,x); calc(c,d,w,y); if(!same(x,y))merge(x,y,w);}int main(){ memset(pa,-1,sizeof(pa)); memset(nxt,-1,sizeof(nxt)); int a,b; Rd(T); while(T--){ memset(head,-1,sizeof(head)); memset(son,0,sizeof(son)); memset(cost,0,sizeof(cost)); cnt=0; Rd(n);Rd(m); for(int i=1;i<n;i++){ fa[i]=i; sum[i]=1; Rd(a);Rd(b); add_edge(a,b); add_edge(b,a); } fa[n]=n;sum[n]=1; for(int i=1;i<=m;i++){ Rd(s[i].a);Rd(s[i].b);Rd(s[i].c);Rd(s[i].d);Rd(s[i].w); } sort(s+1,s+m+1); dfs(1,-1); rdfs(1,-1,1); for(int i=1;i<=m;i++) solve(s[i].a,s[i].b,s[i].c,s[i].d,s[i].w); Pt(sum[1]); putchar(' '); Pt(cost[1]); putchar('\n'); } return 0;}
博主写得比较臭,没进行任何优化,所以很慢,还请读者自己写写看,还是蛮容易的。
阅读全文
2 0
- [HDU6074] Phone Call
- HDU6074 Phone Call(并查集,lca)
- HDU6074 Phone Call(LCA+并查集)
- 6572 Phone call分析
- ios call phone
- phone/call/connection 的关系
- Android调用打电话(Call Phone)
- can I make a cell phone call
- make phone call, browse web, send email
- [转自微软网站]Making a Phone Call in C#
- [MS Smartphone]Make phone call using native c code
- android的call与Phone的实现分析
- android - How to make a phone call from webview
- hdu-6074 Phone Call (LCA+并查集)
- HDU6074(LCA+并查集)
- phone
- IOS 程序内调用本地打电话功能-make a phone call
- Android -- make a phone call using Intent--使用意图拨打电话
- HTTPS和HTTP区别和联系?
- 吴恩达机器学习笔记(1) Ocatave的使用
- CodeForces
- git学习笔记整理-3提交与移除
- 事务的四种隔离级别和七种传播机制
- [HDU6074] Phone Call
- Kotlin Reference (八) Classes and Objects
- node.js测试: 如何利用import / require语法打桩测试指定函数/ 类方法
- FFT 模板(hdu 1402)
- 常用正则表达式
- 一些在线工具
- HDU 6069 Counting Divisors
- cocos骨骼动画
- QML中能使用什么JS库