记录编号 190327 评测结果 AAAAAAAAAA
题目名称 [SPOJ 839] 最优标号 最终得分 100
用户昵称 Gravatar张灵犀不和我一般见识真可怕呢(笑 是否通过 通过
代码语言 C++ 运行时间 0.127 s
提交时间 2015-10-02 22:19:55 内存使用 0.87 MiB
显示代码纯文本
  1. #include<cstdio>
  2. #include<deque>
  3. #include<cmath>
  4. #include<algorithm>
  5. #include<cstring>
  6. #include<iostream>
  7. using namespace std;
  8. const int SIZEN=510,SIZEM=3010,maxn=0x7fffffff/2;
  9. typedef long long LL;
  10. LL ans=0;
  11. int N,M,tot=0,ma=0,K;
  12. bool ok[SIZEN];
  13. int H[SIZEN]={0};
  14. LL e[SIZEN]={0};
  15. LL P[SIZEN]={0},powr[SIZEN]={0};
  16. deque<int> s[SIZEN],w[SIZEN],Q;
  17. class miku
  18. {
  19. public:
  20. int fr,to,cap;
  21. miku(){}
  22. miku(int a,int b,int c)
  23. {
  24. fr=a,to=b,cap=c;
  25. }
  26. }E[SIZEM*6];
  27. void add(int fr,int to,int cap)
  28. {
  29. if(fr==to) return;
  30. s[fr].push_back(tot);
  31. E[tot++]=miku(fr,to,cap);
  32. s[to].push_back(tot);
  33. E[tot++]=miku(to,fr,0);
  34. }
  35. LL min(int a,LL b)
  36. {
  37. if(a<b) return a;
  38. else return b;
  39. }
  40. void read()
  41. {
  42. scanf("%d%d",&N,&M);
  43. int u,v;
  44. for(int i=1;i<=M;i++)
  45. {
  46. scanf("%d%d",&u,&v);
  47. w[u].push_back(v);
  48. w[v].push_back(u);
  49. }
  50. scanf("%d",&K);
  51. int p;
  52. for(int i=1;i<=K;i++)
  53. {
  54. scanf("%d%d",&u,&p);
  55. ok[u]=1;P[u]=p;
  56. if(p>ma) ma=p;
  57. }
  58. for(int i=1;i<=N;i++) add(0,i,0),add(i,N+1,0);
  59. }
  60. void Pow(int a)
  61. {
  62. powr[1]=1;
  63. for(int i=1;powr[i]<ma;i++)
  64. {
  65. powr[i+1]=powr[i]*2;
  66. }
  67. }
  68. void graph(int a)
  69. {
  70. for(int i=1;i<=N;i++)
  71. {
  72. if(ok[i]==1)
  73. {
  74. if((P[i]&a)==0) add(0,i,maxn);
  75. else add(i,N+1,maxn);
  76. }
  77. for(int j=0;j<w[i].size();j++)
  78. add(i,w[i][j],1);
  79. }
  80. }
  81. void push(int x,int t)
  82. {
  83. miku &v=E[t];
  84. LL flow=min(v.cap,e[x]);
  85. e[x]-=flow;v.cap-=flow;e[v.to]+=flow;E[t^1].cap+=flow;
  86. if(v.to!=0&&v.to!=N+1&&e[v.to]>0) Q.push_back(v.to);
  87. }
  88. void use_up(int x)
  89. {
  90. int mi;
  91. while(e[x])
  92. {
  93. mi=maxn;
  94. //cout<<x<<" "<<"H[x]:"<<H[x]<<" "<<"e[x]"<<e[x]<<endl;
  95. for(int i=0;i<s[x].size();i++)
  96. {
  97. miku &v=E[s[x][i]];
  98. //cout<<"v.to:"<<v.to<<" "<<"v.cap:"<<v.cap<<" "<<"H[v.to]:"<<H[v.to]<<endl;
  99. if(v.cap<=0) continue;
  100. if(H[v.to]==H[x]-1)
  101. {
  102. //cout<<e[x]<<endl;
  103. push(x,s[x][i]);
  104. //cout<<e[x]<<endl;
  105. if(!e[x]) break;
  106. }
  107. else if(H[v.to]<mi) mi=H[v.to];
  108. }
  109. if(!e[x]) break;
  110. H[x]=mi+1;
  111. }
  112. }
  113. int maxflow()
  114. {
  115. H[0]=N/2;e[0]=(LL)maxn*100;if(H[0]>10) H[0]=10;
  116. for(int i=0;i<s[0].size();i++) push(0,s[0][i]);
  117. while(!Q.empty())
  118. {
  119. int x=Q.front();Q.pop_front();
  120. //cout<<x<<endl;
  121. use_up(x);
  122. }
  123. return e[N+1];
  124. }
  125. void work()
  126. {
  127. Pow(ma);
  128. for(int i=1;ma>0;ma>>=1,i++)
  129. {
  130. memset(H,0,sizeof(H));memset(e,0,sizeof(e));tot=0;
  131. for(int j=0;j<=N+1;j++) s[j].clear();
  132. graph(powr[i]);
  133. ans+=(maxflow()*powr[i]);
  134. //cout<<"ans:"<<ans<<endl;
  135. //cout<<"*****************"<<endl;
  136. }
  137. cout<<ans<<endl;
  138. }
  139. int main()
  140. {
  141. freopen("optimalmarks.in","r",stdin);
  142. freopen("optimalmarks.out","w",stdout);
  143. read();
  144. work();
  145. return 0;
  146. }