警察叔叔就是这个人!
2017-10-23 16:40
218 查看
给定一个无向有权图,首先一个最小生成树 MST,从 MST 中选取一个度数大于 1 的点 作为根 K,使每颗子树及该子树到根的边权之和方差最小。输出 K 和最小方差的值。
对于60%的数据:3 ≤ N ≤ 2,000,N-1 ≤ M ≤ 50,000
对于100%的数据:3 ≤ N ≤ 40,000,N-1 ≤ M ≤ 200,000
对于100%的数据:0 < len ≤ 100,000,000
首先肯定要搞MST。。。数据大所以kruska
然后dfs把MST搞成一个有根树
有根树上记每个点记以它为根的子树权值和
枚举每一个点,和它连通的部分就是它的每一个子树和整棵树除了它所在的子树以外的各个部分
算一下方差就OJBK
View Code
对于60%的数据:3 ≤ N ≤ 2,000,N-1 ≤ M ≤ 50,000
对于100%的数据:3 ≤ N ≤ 40,000,N-1 ≤ M ≤ 200,000
对于100%的数据:0 < len ≤ 100,000,000
首先肯定要搞MST。。。数据大所以kruska
然后dfs把MST搞成一个有根树
有根树上记每个点记以它为根的子树权值和
枚举每一个点,和它连通的部分就是它的每一个子树和整棵树除了它所在的子树以外的各个部分
算一下方差就OJBK
#include<iostream> #include<cstdlib> #include<algorithm> #include<cstdio> #include<cmath> #include<cstring> const int INF=2147493233; using namespace std; int n,m; struct edge { int from,to; double v; bool operator<(const edge &b)const { return v<b.v; } }edg[439677]; int ans,cnt; int fa[439600]; inline int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);} bool same(int x,int y){return find(x)==find(y);} void link(int x,int y){fa[find(x)]=find(y);} int first[80010],to[80010],next[80010]; double val[80010]; bool tag[40010]; double dp[40010]; bool vis[40010]; int master[40010]; int rank[40010]; inline void add(int u,int v,double w) { to[++cnt]=v; next[cnt]=first[u]; first[u]=cnt; val[cnt]=w; to[++cnt]=u; next[cnt]=first[v]; first[v]=cnt; val[cnt]=w; } void kruskal() { for(int i=0;i<=439600;i++)fa[i]=i; sort(edg+1,edg+m+1); for(int i=1;i<=m;i++) { int u=find(edg[i].from),v=find(edg[i].to); if(u!=v) { fa[u]=v; add(edg[i].from,edg[i].to,edg[i].v); } } } void dfs(int x) { if(vis[x])return; vis[x]=1; for(int i=first[x];i;i=next[i]) { if(!vis[to[i]]) { rank[x]++; dfs(to[i]); master[to[i]]=x; dp[x]+=(dp[to[i]]+val[i]); } } } int a,b; double c; int main() { double ans=2147483233.0; int Ans=0; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d%lf",&a,&b,&c); edg[i]=(edge){a,b,c}; } kruskal(); dfs(1); for(int i=n;i>=1;i--) { int crt=rank[i]+(master[i]!=0); if(crt<2)continue; double sum=0,avg=dp[1]/crt,res=dp[1]-dp[i]; for(int j=first[i];j;j=next[j]) { if(to[j]!=master[i])sum+=(double)(val[j]+dp[to[j]]-avg)*(val[j]+dp[to[j]]-avg); if(i!=1)sum+=(res-avg)*(res-avg); } if(sum<ans) { ans=sum; Ans=i; } } cout<<Ans; return 0; }
View Code
相关文章推荐
- codecomb 2100【警察叔叔就是这个人!】
- codecomb 2100【警察叔叔就是这个人!】
- 模拟赛 警察叔叔就是这个人!
- 警察叔叔就是它!那些烦人的空格!
- 这个人就是吴恩达(Andrew Ng),百度新任首席科学家
- 【正一专栏】警察叔叔,我还是只是一个婴儿
- 警察叔叔智力训练计算1 2 3 4 5 6 7 8 9=110;JAVA实现的两种方式
- 匪警请拨110,即使手机欠费也可拨通!为了保障社会秩序,保护人民群众生命财产安全,警察叔叔需要与罪犯斗智斗勇,
- “我这个人就是比较笨,不知道该怎么看,就是只能一本一本地看”
- 110警察叔叔训练智力
- 匪警请拨110,即使手机欠费也可拨通! 为了保障社会秩序,保护人民群众生命财产安全,警察叔叔需要与罪犯斗智斗勇,因而需要经常性地进行体力训练和智力训练!某批警察叔叔正在进行智力训练:1 2 3 4
- 一天半夜,一个人在马上走遇到了警察叔叔
- 想个办法吓警察叔叔
- 有10(100人或者n个)个人围成一圈,从第一个人开始报数(报1、2、3),只要报3的人就出去, 然后不停的循环报数,直到最后剩下一个人,计算出这个人最开始的位置。其实就是约瑟夫环问题
- 北京的警察就是实在
- 北京的警察就是实在
- 生活就是遇见未知——写在相遇帖之后
- 在oracle中sequence就是序号,每次取的时候它会自动增加。sequence与表没有关系
- 就是这样
- mysql 最重要的一点使用客户端的终端神器的开启命令行!就是输代码的!还有就是继续 mysql的查找!