[关闭]
@winee 2017-10-12T07:45:33.000000Z 字数 2563 阅读 848

T2 attack 题解

将病毒按攻击力从小到大排序,网线也从小到大排序,一个病毒能入侵的网络比它强的病毒也能入侵,如果病毒攻击力递增,下一个病毒可入侵网络在此基础上扩展即可,每个节点只扩展一次,不会撤销,每次将病毒可入侵的边加入,用并查集维护连通块の利润和,最高重要度及其个数,并统计这次入侵的连通块,注意判重。然后,50分就有了?!

此题卡常数,需要一个给力的输入输出优化

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. using namespace std;
  5. typedef long long LL;
  6. #define BUFSIZE 300000
  7. namespace fib {char b[BUFSIZE]={},*f=b;}
  8. #define gc ((*fib::f)?(*(fib::f++)):(fgets(fib::b,sizeof(fib::b),stdin)?(fib::f=fib::b,*(fib::f++)):-1))
  9. void read(int &tmp) {
  10. tmp=0; bool fu=0; char s;
  11. while(s=gc,s!='-'&&(s<'0'||s>'9')) ;
  12. if(s=='-') fu=1; else tmp=s-'0';
  13. while(s=gc,s>='0'&&s<='9') tmp=tmp*10+s-'0';
  14. if(fu) tmp = -tmp;
  15. }
  16. void read(LL &tmp) {
  17. tmp=0; bool fu=0; char s;
  18. while(s=gc,s!='-'&&(s<'0'||s>'9')) ;
  19. if(s=='-') fu=1; else tmp=s-'0';
  20. while(s=gc,s>='0'&&s<='9') tmp=tmp*10+s-'0';
  21. if(fu) tmp = -tmp;
  22. }
  23. namespace fob {char b[BUFSIZE]={},*f=b,*g=b+BUFSIZE-2;}
  24. #define pob (fwrite(fob::b,sizeof(char),fob::f-fob::b,stdout),fob::f=fob::b,0)
  25. #define pc(x) (*(fob::f++)=(x),(fob::f==fob::g)?pob:0)
  26. struct foce {~foce() {pob; fflush(stdout);}} _foce;
  27. namespace ib {char b[100];}
  28. inline void pint(LL x) {
  29. if(x==0) {pc(48); return;}
  30. if(x<0) {pc('-'); x=-x;}
  31. char *s=ib::b;
  32. while(x) *(++s)=x%10, x/=10;
  33. while(s!=ib::b) pc((*(s--))+48);
  34. }
  35. #define N 410000
  36. struct E {int to,next;}g[3010000];
  37. int fr[N],tot;
  38. void Add(int from,int to) {
  39. g[++tot].to = to;
  40. g[tot].next = fr[from];
  41. fr[from] = tot;
  42. }
  43. int n,m,q,num[N],val[N],rk[N],rke[N],x[N],y[N],v[N];
  44. int f[N];
  45. LL ans1[N],ans2[N],hs[N],ha[N],b[N];
  46. inline bool cmp(const int &a,const int &b) {return val[a] < val[b];}
  47. inline bool cmpe(const int &a,const int &b) {return v[a] < v[b];}
  48. inline int fd(int x) {
  49. return f[x]==x ? x : f[x]=fd(f[x]);
  50. }
  51. inline void Mer(int x,int y) {
  52. x = fd(x); y = fd(y);
  53. if(x != y) {
  54. f[x] = y;
  55. b[y] += b[x];
  56. if(ha[y] == ha[x]) hs[y] += hs[x];
  57. else if(ha[y] < ha[x]) hs[y] = hs[x],ha[y] = ha[x];
  58. }
  59. }
  60. int le = 1;bool done[N];
  61. inline void slove(int t) {
  62. LL tp1 = 0,tp2 = 0,hha = 0;
  63. while(le <= m && v[rke[le]] <= val[t]) {Mer(x[rke[le]],y[rke[le]]);le++;}
  64. for (int i = fr[t]; i; i = g[i].next) {
  65. int po = fd(g[i].to);
  66. if (!done[po]) {
  67. done[po] = 1;
  68. if(ha[po] > hha) tp1 = ha[po]*hs[po],hha = ha[po];
  69. else if(ha[po] == hha) tp1 += ha[po]*hs[po];
  70. tp2 += b[po];
  71. }
  72. }
  73. for (int i = fr[t]; i; i = g[i].next) done[fd(g[i].to)] = 0;
  74. ans1[t] = tp1; ans2[t] = tp2;
  75. }
  76. int main() {
  77. freopen("attack.in","r",stdin);freopen("attack.out","w",stdout);
  78. read(n); read(m); read(q); LL totb = 0;
  79. for (int i = 1; i <= n; i++) read(ha[i]),f[i] = i,hs[i] = 1;;
  80. for (int i = 1; i <= n; i++) read(b[i]),totb += b[i];
  81. for (int i = 1; i <= m; i++) read(x[i]),read(y[i]),read(v[i]),rke[i] = i;;
  82. for (int i = 1; i <= q; i++) {
  83. read(num[i]),read(val[i]);rk[i] = i;
  84. for (int j = 1,tp; j <= num[i]; j++) {
  85. read(tp);
  86. Add(i,tp);
  87. }
  88. }
  89. sort(rk+1,rk+q+1,cmp); sort(rke+1,rke+m+1,cmpe);
  90. for (int i = 1; i <= q; i++) slove(rk[i]);
  91. for (int i = 1; i <= q; i++) pint(ans1[i]),pc(' '),pint(totb-ans2[i]),pc('\n');
  92. return 0;
  93. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注