BZOJ 3308 September coffee shop fee Flow
In [1, n] Select a number in the interval so that these numbers are mutually qualitative and calculate the maximum value of the sum of these numbers.
It is easy to find that for an optimal solution, each prime number exists and only exists in one number. (Nonsense.
However, there may be multiple prime numbers in a single number.
The following are two conclusions:
1. A number can contain at most two different prime numbers.
2. One of the two prime numbers , One > N √
MeCompleteI won't prove these two conclusions. Both conclusions are officially answered.
Then we can do it. Prime Number and > N √ Build a bipartite graph of the prime number, and find the maximum cost flow.
But this will not happen because the figure is too large.
Therefore, we have two pruning methods:
1. > N2 The prime number of must exist independently in the solution set. You do not need to throw it into the bipartite graph to run it.
2. If a combination of two prime numbers is better to get the largest and add up respectively, this edge will not be added.
After adding it, you will be able ...... Points ran 9 s +
This question is 355 of PE. I heard that all the people in PE are running simulated annealing?
It is said that it is very fast ......
#include
#include
#include
#include #define M 10100#define S 0#define T (M-1)#define INF 0x3f3f3f3fusing namespace std;int n;long long ans;int prime[M<<2],tot;bool not_prime[200200];namespace Max_Cost_Max_Flow{ struct abcd{ int to,flow,cost,next; }table[100100]; int head[M],tot=1; void Add(int x,int y,int f,int c) { table[++tot].to=y; table[tot].flow=f; table[tot].cost=c; table[tot].next=head[x]; head[x]=tot; } void Link(int x,int y,int f,int c) { Add(x,y,f,c); Add(y,x,0,-c); } bool Edmonds_Karp() { static int q[65540],cost[M],from[M]; static unsigned short r,h; static bool v[M]; int i; memset(cost,0xef,sizeof cost); cost[S]=0;q[++r]=S; while(r!=h) { int x=q[++h];v[x]=false; for(i=head[x];i;i=table[i].next) if(table[i].flow&&cost[table[i].to]
=x) n/=x,re*=x; return re;}int main(){ int i,j; cin>>n; Linear_Shaker(); for(i=1;i<=tot&&prime[i]*2<=n;i++) if((long long)prime[i]*prime[i]<=n) { Max_Cost_Max_Flow::Link(S,i,1,0); Max_Cost_Max_Flow::Link(i,T,1,Get_Max(n,prime[i])); } else { Max_Cost_Max_Flow::Link(i,T,1,0); Max_Cost_Max_Flow::Link(S,i,1,prime[i]); } for(;i<=tot;i++) ans+=prime[i]; for(i=1;i<=tot&&(long long)prime[i]*prime[i]<=n;i++); for(;i<=tot&&prime[i]*2<=n;i++) for(j=1;j<=tot&&(long long)prime[j]*prime[j]<=n;j++) { if(prime[i]*prime[j]>n) break; int temp=Get_Max(n/prime[i],prime[j])*prime[i]; if(temp>Get_Max(n,prime[j])+prime[i]) Max_Cost_Max_Flow::Link(j,i,1,temp); } while( Max_Cost_Max_Flow::Edmonds_Karp() ); cout<