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

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

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

  1. #include <bits/stdc++.h>
  2. #define mid ((l+r)>>1)
  3. #define MAXN 200010 //节点数目
  4. using namespace std;
  5. typedef long long ll;
  6.  
  7. vector<pair<int,int> >v[MAXN];
  8. int fa[MAXN];
  9. int deg[MAXN];
  10. int num[MAXN];
  11. int son[MAXN];
  12. int top[MAXN];
  13. int w[MAXN];//每个和对应子节点相连的边对应的编号
  14. int tot;//边的编号
  15. int tree[MAXN<<];
  16. void dfs1(int s,int d)
  17. {
  18. deg[s]=d,num[s]=,son[s]=;
  19. for(int i=;i<v[s].size();i++)
  20. {
  21. int t=v[s][i].first;
  22. if(t==fa[s])
  23. continue;
  24. fa[t]=s;
  25. dfs1(t,d+);
  26. num[s]+=num[t];
  27. if(num[t]>num[son[s]])
  28. son[s]=t;
  29. }
  30. }
  31. void dfs2(int s,int tp)
  32. {
  33. top[s]=tp;
  34. if(son[s])
  35. {
  36. w[son[s]]=++tot;
  37. dfs2(son[s],tp);
  38. }
  39. for(int i=;i<v[s].size();i++)
  40. {
  41. int t=v[s][i].first;
  42. if(t==fa[s]||t==son[s])
  43. continue;
  44. w[t]=++tot;
  45. dfs2(t,t);
  46. }
  47. }
  48. void update(int le,int ri,int val,int l,int r,int n)//区间更改,在这个程序中一定有le==ri,所以退化成单点更新
  49. {
  50. if(l==r)
  51. {
  52. tree[n]=val;
  53. return;
  54. }
  55. if(le<=mid)
  56. update(le,le,val,l,mid,n<<);
  57. else update(le,le,val,mid+,r,n<<|);
  58. tree[n]=max(tree[n<<],tree[n<<|]);
  59. }
  60. int query(int le,int ri,int l,int r,int n)
  61. {
  62. if(le==l&&ri==r)
  63. return tree[n];
  64. if(ri<=mid)
  65. return query(le,ri,l,mid,n<<);
  66. else if(le>mid)
  67. return query(le,ri,mid+,r,n<<|);
  68. else return max(query(le,mid,l,mid,n<<),query(mid+,ri,mid+,r,n<<|));
  69. }
  70. int find(int s,int t,int n)
  71. {
  72. int s1=top[s],t1=top[t],ans=;
  73. while(s1!=t1)
  74. {
  75. if(deg[s1]<deg[t1])
  76. {
  77. swap(s1,t1);
  78. swap(s,t);
  79. }
  80. ans=max(ans,query(w[s1],w[s],,n,));
  81. s=fa[s1];s1=top[s];
  82. }
  83. if(s!=t)
  84. {
  85. if(deg[s]<deg[t])
  86. swap(s,t);
  87. return max(ans,query(w[son[t]],w[s],,n,));
  88. }
  89. return ans;
  90. }
  91. int change(int s,int t,int c,int n)
  92. {
  93. int s1=top[s],t1=top[t];
  94. while(s1!=t1)
  95. {
  96. if(deg[s1]<deg[t1])
  97. {
  98. swap(s1,t1);
  99. swap(s,t);
  100. }
  101. update(w[s1],w[s],c,,n,);
  102. s=fa[s1];s1=top[s];
  103. }
  104. if(s!=t)
  105. {
  106. if(deg[s]<deg[t])
  107. swap(s,t);
  108. update(w[son[t]],w[s],c,,n,);
  109. }
  110. }
  111. vector<pair<int,int> >v2[MAXN];
  112. int val1[MAXN],val2[MAXN];
  113. bool sign[MAXN];
  114. int nu[MAXN];
  115. int fa2[MAXN];
  116. set<pair<int,int> >s;
  117. int minn=-;
  118. ll anss=;
  119. void prime(int t,int n)
  120. {
  121. sign[t]=true;
  122. for(int i=;i<v2[t].size();i++)
  123. {
  124. int t2=v2[t][i].first;
  125. if(nu[t2]&&val1[nu[t2]]>val1[v2[t][i].second])
  126. s.erase(s.find(make_pair(val1[nu[t2]],t2)));
  127. else if(nu[t2])
  128. continue;
  129. nu[t2]=v2[t][i].second;
  130. fa2[t2]=t;
  131. s.insert(make_pair(val1[nu[t2]],t2));
  132. }
  133. for(int i=;i<n;i++)
  134. {
  135. pair<int,int>temp=*s.begin();
  136. s.erase(s.begin());
  137. int t=temp.second;
  138. sign[t]=true;
  139. anss+=val1[nu[t]];
  140. v[fa2[t]].push_back(make_pair(t,nu[t]));
  141. if(minn==-||val2[nu[t]]<val2[minn])
  142. minn=nu[t];
  143. for(int i=;i<v2[t].size();i++)
  144. {
  145. int t2=v2[t][i].first;
  146. if(sign[t2])
  147. continue;
  148. if(nu[t2]&&val1[nu[t2]]>val1[v2[t][i].second])
  149. s.erase(s.find(make_pair(val1[nu[t2]],t2)));
  150. else if(nu[t2])
  151. continue;
  152. nu[t2]=v2[t][i].second;
  153. fa2[t2]=t;
  154. s.insert(make_pair(val1[nu[t2]],t2));
  155. }
  156. }
  157. }
  158. int a,b,c;
  159. pair<int,int>p[MAXN];
  160. int ss[MAXN],tt[MAXN];
  161. int main()
  162. {
  163. int n,m;
  164. scanf("%d%d",&n,&m);
  165. for(int i=;i<=m;i++)
  166. scanf("%d",&val1[i]);
  167. for(int i=;i<=m;i++)
  168. scanf("%d",&val2[i]);
  169. for(int i=;i<=m;i++)
  170. {
  171. scanf("%d%d",&a,&b);
  172. ss[i]=a;
  173. tt[i]=b;
  174. v2[a].push_back(make_pair(b,i));
  175. v2[b].push_back(make_pair(a,i));
  176. }
  177. int budget;
  178. scanf("%d",&budget);
  179. prime(,n);
  180. fa[]=;
  181. dfs1(,);
  182. tot=;
  183. dfs2(,);
  184. for(int i=;i<=n;i++)
  185. {
  186. a=i;
  187. for(int j=;j<v[i].size();j++)
  188. {
  189. b=v[i][j].first;
  190. c=val1[v[i][j].second];
  191. change(a,b,c,n-);//修改a,b之间路径值为c;
  192. }
  193. }
  194. for(int i=;i<=m;i++)
  195. {
  196. p[i].first=val2[i];
  197. p[i].second=i;
  198. }
  199. sort(p+,p++m);
  200. int maxn=;
  201. int fin=minn;
  202. int fansile;
  203. for(int i=;i<=m;i++)
  204. {
  205. int numb=p[i].second;
  206. if(numb==minn)
  207. break;
  208. int temp=find(ss[numb],tt[numb],n-);
  209. int curr=val1[numb]-temp;
  210. curr-=(budget/val2[numb])-(budget/val2[minn]);
  211. if(maxn>curr)
  212. {
  213. maxn=curr;
  214. fin=numb;
  215. fansile=temp;
  216. }
  217. }
  218. if(fin==minn)
  219. {
  220. printf("%lld\n",anss-budget/val2[minn]);
  221. for(int i=;i<=n;i++)
  222. {
  223. for(int j=;j<v[i].size();j++)
  224. {
  225. int numb=v[i][j].second;
  226. if(numb==minn)
  227. printf("%d %d\n",numb,val1[numb]-budget/val2[numb]);
  228. else
  229. printf("%d %d\n",numb,val1[numb]);
  230. }
  231. }
  232. }
  233. else
  234. {
  235. int caos=ss[fin],caot=tt[fin];
  236. int caos2=caos,caot2=caot;
  237. int mubiao;
  238. while()
  239. {
  240. int tops=top[caos2];
  241. int topt=top[caot2];
  242. if(tops==topt)
  243. {
  244. if(deg[caos2]<deg[caot2])
  245. mubiao=caos2;
  246. else mubiao=caot2;
  247. break;
  248. }
  249. else if(deg[tops]<deg[topt])
  250. caot2=fa[topt];
  251. else caos2=fa[tops];
  252. if(caos2==caot2)
  253. {
  254. mubiao=caos2;
  255. break;
  256. }
  257. }
  258. bool ok=false;
  259. int mubiao2;
  260. while(caos!=mubiao)
  261. {
  262. if(val1[nu[caos]]==fansile)
  263. {
  264. ok=true;
  265. mubiao2=nu[caos];
  266. break;
  267. }
  268. caos=fa2[caos];
  269. }
  270. while(!ok&&caot!=mubiao)
  271. {
  272. if(val1[nu[caot]]==fansile)
  273. {
  274. ok=true;
  275. mubiao2=nu[caot];
  276. break;
  277. }
  278. caot=fa2[caot];
  279. }
  280. printf("%I64d\n",anss+maxn-budget/val2[minn]);
  281. for(int i=;i<=n;i++)
  282. {
  283. for(int j=;j<v[i].size();j++)
  284. {
  285. if(v[i][j].second==mubiao2)
  286. continue;
  287. printf("%d %d\n",v[i][j].second,val1[v[i][j].second]);
  288. }
  289. }
  290. printf("%d %d\n",fin,val1[fin]-budget/val2[fin]);
  291. }
  292. return ;
  293. }

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. bootstrap-滚动监听

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  2. IComparable<T> Vs. IComparer<T> System.Comparison<T>

    Well they are not quite the same thing as IComparer<T> is implemented on a type that is capabl ...

  3. linux下搭建sock5代理

    VPN大家耳熟能详,但是socks用到的人比较少,那什么是socks呢?请看第二段或者百度百科,socks分别有4和5两个版本,现在5为主流.工作中经常用VPN访问国外,但是同时国内的速度又慢了,让人 ...

  4. yum:在Red Hat和Fedora中使用

    1.列出已安装包: yum list installed--------->输出的结果可能在屏幕上一闪而过.所以最好把已安装包的列表重定义到一个文件中.然后是使用more/less查看 yum ...

  5. Python基础语法,基本数据类型及相关操作

    ---恢复内容开始--- python文件 文件开头要有  #!/usr/bin/ python        --在linux中是告诉系统phthon的路径是在/usr/bin/ python目录下 ...

  6. [ActionScript 3.0] 对代码加密的有效方法

    package { import flash.display.Loader; import flash.display.Sprite; import flash.net.LocalConnection ...

  7. MVC 访问IFrame页面Session过期后跳转到登录页面

    Web端开发时,用户登录后往往会通过Session来保存用户信息,Session存放在服务器,当用户长时间不操作的时候,我们会希望服务器保存的Session过期,这个时候,因为Session中的用户信 ...

  8. js判断浏览器

    function myBrowser(){ var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 ; if (isOpera) { ret ...

  9. [转载]Vivado轻松实现IP封装

    Vivado轻松实现IP封装 1.新建一个测试工程 工程化的设计方法是离不开工程的,第一步往往都是新建工程,后面我会学习去工程化的开发方法,可能会更加高效. 2.利用向导完成IP封装 2.1.启动IP ...

  10. Java 2D API - 2. Graphics 入门

    Java 2D API强大而复杂,不过大多时候我们只需使用java.awt.Graphcis类的部分功能.下面的内容将覆盖大多数的常见应用. Graphics 类中的方法大致可以分为两类: Draw ...