给你很多条边,每条边有一个初始边权w1,然后还有一个值表示把这个边权减一的代价w2,然后给你一个预算budget,然后让你输出怎么选边之后构成的树的边权和最小(在用budget减少了边权之后),输出你选的每一条边以及该边此时的边权.

思路:首先显然预算都要用到你选的那棵树上w2最小的那条边上,然后就看你怎么选树,我的思路是:先prime选出最小生成树并记录现在的边上最小的w2,然后树链剖分,用线段树记录路径上边的边权的最大值.然后把所有的边按w2排序,当还有边的w2小于记录的最小的w2的时候,求出把这条边加进去并把形成的环上w1最大的那个边去掉能得到的答案,和之前的答案进行比较,从而找出最优的,由于最小生成树其实可能有很多种不同的我并不能保证我的思路对,但是考虑到最小生成树其实还是比较特殊的,可以推测不同的最小生成树得到的答案是一样的,我就这么做了,果然对了.

写道后面感觉好烦,就特别暴力了一下,反正后面的那部分耗时不大.

#include <bits/stdc++.h>
#define mid ((l+r)>>1)
#define MAXN 200010 //节点数目
using namespace std;
typedef long long ll; vector<pair<int,int> >v[MAXN];
int fa[MAXN];
int deg[MAXN];
int num[MAXN];
int son[MAXN];
int top[MAXN];
int w[MAXN];//每个和对应子节点相连的边对应的编号
int tot;//边的编号
int tree[MAXN<<];
void dfs1(int s,int d)
{
deg[s]=d,num[s]=,son[s]=;
for(int i=;i<v[s].size();i++)
{
int t=v[s][i].first;
if(t==fa[s])
continue;
fa[t]=s;
dfs1(t,d+);
num[s]+=num[t];
if(num[t]>num[son[s]])
son[s]=t;
}
}
void dfs2(int s,int tp)
{
top[s]=tp;
if(son[s])
{
w[son[s]]=++tot;
dfs2(son[s],tp);
}
for(int i=;i<v[s].size();i++)
{
int t=v[s][i].first;
if(t==fa[s]||t==son[s])
continue;
w[t]=++tot;
dfs2(t,t);
}
}
void update(int le,int ri,int val,int l,int r,int n)//区间更改,在这个程序中一定有le==ri,所以退化成单点更新
{
if(l==r)
{
tree[n]=val;
return;
}
if(le<=mid)
update(le,le,val,l,mid,n<<);
else update(le,le,val,mid+,r,n<<|);
tree[n]=max(tree[n<<],tree[n<<|]);
}
int query(int le,int ri,int l,int r,int n)
{
if(le==l&&ri==r)
return tree[n];
if(ri<=mid)
return query(le,ri,l,mid,n<<);
else if(le>mid)
return query(le,ri,mid+,r,n<<|);
else return max(query(le,mid,l,mid,n<<),query(mid+,ri,mid+,r,n<<|));
}
int find(int s,int t,int n)
{
int s1=top[s],t1=top[t],ans=;
while(s1!=t1)
{
if(deg[s1]<deg[t1])
{
swap(s1,t1);
swap(s,t);
}
ans=max(ans,query(w[s1],w[s],,n,));
s=fa[s1];s1=top[s];
}
if(s!=t)
{
if(deg[s]<deg[t])
swap(s,t);
return max(ans,query(w[son[t]],w[s],,n,));
}
return ans;
}
int change(int s,int t,int c,int n)
{
int s1=top[s],t1=top[t];
while(s1!=t1)
{
if(deg[s1]<deg[t1])
{
swap(s1,t1);
swap(s,t);
}
update(w[s1],w[s],c,,n,);
s=fa[s1];s1=top[s];
}
if(s!=t)
{
if(deg[s]<deg[t])
swap(s,t);
update(w[son[t]],w[s],c,,n,);
}
}
vector<pair<int,int> >v2[MAXN];
int val1[MAXN],val2[MAXN];
bool sign[MAXN];
int nu[MAXN];
int fa2[MAXN];
set<pair<int,int> >s;
int minn=-;
ll anss=;
void prime(int t,int n)
{
sign[t]=true;
for(int i=;i<v2[t].size();i++)
{
int t2=v2[t][i].first;
if(nu[t2]&&val1[nu[t2]]>val1[v2[t][i].second])
s.erase(s.find(make_pair(val1[nu[t2]],t2)));
else if(nu[t2])
continue;
nu[t2]=v2[t][i].second;
fa2[t2]=t;
s.insert(make_pair(val1[nu[t2]],t2));
}
for(int i=;i<n;i++)
{
pair<int,int>temp=*s.begin();
s.erase(s.begin());
int t=temp.second;
sign[t]=true;
anss+=val1[nu[t]];
v[fa2[t]].push_back(make_pair(t,nu[t]));
if(minn==-||val2[nu[t]]<val2[minn])
minn=nu[t];
for(int i=;i<v2[t].size();i++)
{
int t2=v2[t][i].first;
if(sign[t2])
continue;
if(nu[t2]&&val1[nu[t2]]>val1[v2[t][i].second])
s.erase(s.find(make_pair(val1[nu[t2]],t2)));
else if(nu[t2])
continue;
nu[t2]=v2[t][i].second;
fa2[t2]=t;
s.insert(make_pair(val1[nu[t2]],t2));
}
}
}
int a,b,c;
pair<int,int>p[MAXN];
int ss[MAXN],tt[MAXN];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
scanf("%d",&val1[i]);
for(int i=;i<=m;i++)
scanf("%d",&val2[i]);
for(int i=;i<=m;i++)
{
scanf("%d%d",&a,&b);
ss[i]=a;
tt[i]=b;
v2[a].push_back(make_pair(b,i));
v2[b].push_back(make_pair(a,i));
}
int budget;
scanf("%d",&budget);
prime(,n);
fa[]=;
dfs1(,);
tot=;
dfs2(,);
for(int i=;i<=n;i++)
{
a=i;
for(int j=;j<v[i].size();j++)
{
b=v[i][j].first;
c=val1[v[i][j].second];
change(a,b,c,n-);//修改a,b之间路径值为c;
}
}
for(int i=;i<=m;i++)
{
p[i].first=val2[i];
p[i].second=i;
}
sort(p+,p++m);
int maxn=;
int fin=minn;
int fansile;
for(int i=;i<=m;i++)
{
int numb=p[i].second;
if(numb==minn)
break;
int temp=find(ss[numb],tt[numb],n-);
int curr=val1[numb]-temp;
curr-=(budget/val2[numb])-(budget/val2[minn]);
if(maxn>curr)
{
maxn=curr;
fin=numb;
fansile=temp;
}
}
if(fin==minn)
{
printf("%lld\n",anss-budget/val2[minn]);
for(int i=;i<=n;i++)
{
for(int j=;j<v[i].size();j++)
{
int numb=v[i][j].second;
if(numb==minn)
printf("%d %d\n",numb,val1[numb]-budget/val2[numb]);
else
printf("%d %d\n",numb,val1[numb]);
}
}
}
else
{
int caos=ss[fin],caot=tt[fin];
int caos2=caos,caot2=caot;
int mubiao;
while()
{
int tops=top[caos2];
int topt=top[caot2];
if(tops==topt)
{
if(deg[caos2]<deg[caot2])
mubiao=caos2;
else mubiao=caot2;
break;
}
else if(deg[tops]<deg[topt])
caot2=fa[topt];
else caos2=fa[tops];
if(caos2==caot2)
{
mubiao=caos2;
break;
}
}
bool ok=false;
int mubiao2;
while(caos!=mubiao)
{
if(val1[nu[caos]]==fansile)
{
ok=true;
mubiao2=nu[caos];
break;
}
caos=fa2[caos];
}
while(!ok&&caot!=mubiao)
{
if(val1[nu[caot]]==fansile)
{
ok=true;
mubiao2=nu[caot];
break;
}
caot=fa2[caot];
}
printf("%I64d\n",anss+maxn-budget/val2[minn]);
for(int i=;i<=n;i++)
{
for(int j=;j<v[i].size();j++)
{
if(v[i][j].second==mubiao2)
continue;
printf("%d %d\n",v[i][j].second,val1[v[i][j].second]);
}
}
printf("%d %d\n",fin,val1[fin]-budget/val2[fin]);
}
return ;
}

cf 733f的更多相关文章

  1. ORA-00494: enqueue [CF] held for too long (more than 900 seconds) by 'inst 1, osid 5166'

    凌晨收到同事电话,反馈应用程序访问Oracle数据库时报错,当时现场现象确认: 1. 应用程序访问不了数据库,使用SQL Developer测试发现访问不了数据库.报ORA-12570 TNS:pac ...

  2. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  3. cf Round 613

    A.Peter and Snow Blower(计算几何) 给定一个点和一个多边形,求出这个多边形绕这个点旋转一圈后形成的面积.保证这个点不在多边形内. 画个图能明白 这个图形是一个圆环,那么就是这个 ...

  4. ARC下OC对象和CF对象之间的桥接(bridge)

    在开发iOS应用程序时我们有时会用到Core Foundation对象简称CF,例如Core Graphics.Core Text,并且我们可能需要将CF对象和OC对象进行互相转化,我们知道,ARC环 ...

  5. [Recommendation System] 推荐系统之协同过滤(CF)算法详解和实现

    1 集体智慧和协同过滤 1.1 什么是集体智慧(社会计算)? 集体智慧 (Collective Intelligence) 并不是 Web2.0 时代特有的,只是在 Web2.0 时代,大家在 Web ...

  6. CF memsql Start[c]UP 2.0 A

    CF memsql Start[c]UP 2.0 A A. Golden System time limit per test 1 second memory limit per test 256 m ...

  7. CF memsql Start[c]UP 2.0 B

    CF memsql Start[c]UP 2.0 B B. Distributed Join time limit per test 1 second memory limit per test 25 ...

  8. CF #376 (Div. 2) C. dfs

    1.CF #376 (Div. 2)    C. Socks       dfs 2.题意:给袜子上色,使n天左右脚袜子都同样颜色. 3.总结:一开始用链表存图,一直TLE test 6 (1)如果需 ...

  9. CF #375 (Div. 2) D. bfs

    1.CF #375 (Div. 2)  D. Lakes in Berland 2.总结:麻烦的bfs,但其实很水.. 3.题意:n*m的陆地与水泽,水泽在边界表示连通海洋.最后要剩k个湖,总要填掉多 ...

随机推荐

  1. iOS开发 - OC - 苹果为大家提供的后台:CloudKit 的简单使用

    一.什么是cloudKit 移动开发中,网络请求数据是日常中用到的,我们习惯把一些用户改动的数据存在服务器,以便下次请求使用.或者开发者方通过服务器将编辑的数据发送给用户.但是这一切都建立在我们的AP ...

  2. 02-C#入门(枚举、结构等)

    不要为了写笔记而学习!!! 其实学完一章再返回复习,然后做笔记,真的很费时间(电子书还不方便).当然,复习带来的价值,是值得花时间的. 枚举.结构 枚举的类型有限(short.byte...)且是相同 ...

  3. 文本XSS攻击过滤

    在FCK或百度编辑器等常用富文本编辑器中,通常是会被XSS攻击 处理方法: 文本框模拟输入了以下文本 <span style="dispaly:none" onclick=& ...

  4. 一次性插入多条sql语句的几种方法

    第一种:通过 insert select语句向表中添加数据 从现有表里面把数据插入到另外一张新表去前提必须先有test_2表的存在,并且test_2表中的列的数据类型必须和test表里面列的数据类型一 ...

  5. find命令和tar命令的使用

    tar命令 tar -zcvf small.tar.gz small(目录名) (压缩) tar -zxvf small.tar.gz -C small(目录名) (解压到指定目录) find 命令 ...

  6. javascript_this的用法

    javascript : this的用法 1.this代表全局对象 2.作为函数对象的公共方法(new对象后,可以调用带this关键字的属性) 总结:如果在javascript语言里没有通过new(包 ...

  7. vs快捷键汇总

    1.相关查找快捷键 Ctrl+F: 查找 Ctrl+Shift+F: 在文件中查找 F3: 查找下一个 Shift+F3: 查找上一个 Ctrl+H: 替换 Ctrl+Shift+H: 在文件中替换 ...

  8. sencha touch打包成安装程序

    为了更好地向大家演示如何打包一个sencha touch的项目,我们用sencha cmd创建一个演示项目,如果你的sencha cmd环境还没有配置,请参照 sencha touch 入门系列 (二 ...

  9. setFeatureInt、android 自定义标题栏

    Android 自带的toolbar 往往不能很好的的满足我们的个性化要求.因此我们经常使用自定的的标题栏.而Android系统本身也允许我们自定以标题栏. 记录一下,自定义标题栏常遇到的问题.先上效 ...

  10. bash 相关的一些小代码片断

    批量修改文件名: for i in *.html; do mv $i ${i/oldstring/newstring}; done; 批量替换文件内容: sed -i "s/oldstrin ...