显示代码纯文本
- #include<cstdio>
- #include<deque>
- #include<cmath>
- #include<algorithm>
- #include<cstring>
- #include<iostream>
- using namespace std;
- const int SIZEN=510,SIZEM=3010,maxn=0x7fffffff/2;
- typedef long long LL;
- LL ans=0;
- int N,M,tot=0,ma=0,K;
- bool ok[SIZEN];
- int H[SIZEN]={0};
- LL e[SIZEN]={0};
- LL P[SIZEN]={0},powr[SIZEN]={0};
- deque<int> s[SIZEN],w[SIZEN],Q;
- class miku
- {
- public:
- int fr,to,cap;
- miku(){}
- miku(int a,int b,int c)
- {
- fr=a,to=b,cap=c;
- }
- }E[SIZEM*6];
- void add(int fr,int to,int cap)
- {
- if(fr==to) return;
- s[fr].push_back(tot);
- E[tot++]=miku(fr,to,cap);
- s[to].push_back(tot);
- E[tot++]=miku(to,fr,0);
- }
- LL min(int a,LL b)
- {
- if(a<b) return a;
- else return b;
- }
- void read()
- {
- scanf("%d%d",&N,&M);
- int u,v;
- for(int i=1;i<=M;i++)
- {
- scanf("%d%d",&u,&v);
- w[u].push_back(v);
- w[v].push_back(u);
- }
- scanf("%d",&K);
- int p;
- for(int i=1;i<=K;i++)
- {
- scanf("%d%d",&u,&p);
- ok[u]=1;P[u]=p;
- if(p>ma) ma=p;
- }
- for(int i=1;i<=N;i++) add(0,i,0),add(i,N+1,0);
- }
- void Pow(int a)
- {
- powr[1]=1;
- for(int i=1;powr[i]<ma;i++)
- {
- powr[i+1]=powr[i]*2;
- }
- }
- void graph(int a)
- {
- for(int i=1;i<=N;i++)
- {
- if(ok[i]==1)
- {
- if((P[i]&a)==0) add(0,i,maxn);
- else add(i,N+1,maxn);
- }
- for(int j=0;j<w[i].size();j++)
- add(i,w[i][j],1);
- }
- }
- void push(int x,int t)
- {
- miku &v=E[t];
- LL flow=min(v.cap,e[x]);
- e[x]-=flow;v.cap-=flow;e[v.to]+=flow;E[t^1].cap+=flow;
- if(v.to!=0&&v.to!=N+1&&e[v.to]>0) Q.push_back(v.to);
- }
- void use_up(int x)
- {
- int mi;
- while(e[x])
- {
- mi=maxn;
- //cout<<x<<" "<<"H[x]:"<<H[x]<<" "<<"e[x]"<<e[x]<<endl;
- for(int i=0;i<s[x].size();i++)
- {
- miku &v=E[s[x][i]];
- //cout<<"v.to:"<<v.to<<" "<<"v.cap:"<<v.cap<<" "<<"H[v.to]:"<<H[v.to]<<endl;
- if(v.cap<=0) continue;
- if(H[v.to]==H[x]-1)
- {
- //cout<<e[x]<<endl;
- push(x,s[x][i]);
- //cout<<e[x]<<endl;
- if(!e[x]) break;
- }
- else if(H[v.to]<mi) mi=H[v.to];
- }
- if(!e[x]) break;
- H[x]=mi+1;
- }
- }
- int maxflow()
- {
- H[0]=N/2;e[0]=(LL)maxn*100;if(H[0]>10) H[0]=10;
- for(int i=0;i<s[0].size();i++) push(0,s[0][i]);
- while(!Q.empty())
- {
- int x=Q.front();Q.pop_front();
- //cout<<x<<endl;
- use_up(x);
- }
- return e[N+1];
- }
- void work()
- {
- Pow(ma);
- for(int i=1;ma>0;ma>>=1,i++)
- {
- memset(H,0,sizeof(H));memset(e,0,sizeof(e));tot=0;
- for(int j=0;j<=N+1;j++) s[j].clear();
- graph(powr[i]);
- ans+=(maxflow()*powr[i]);
- //cout<<"ans:"<<ans<<endl;
- //cout<<"*****************"<<endl;
- }
- cout<<ans<<endl;
- }
- int main()
- {
- freopen("optimalmarks.in","r",stdin);
- freopen("optimalmarks.out","w",stdout);
- read();
- work();
- return 0;
- }