zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 21 F. Card Game(网络流之最大点权独立集)

    题目链接:Educational Codeforces Round 21 F. Card Game

    题意:

    有n个卡片,每个卡片有三个值:p,c,l;

    现在让你找一个最小的L,使得满足选出来的卡片l<=L,并且所有卡片的p的和不小于k。

    选择卡片时有限制,任意两张卡片的c之和不能为质数。

    题解:

    hdu 1565 方格取数(2)一样,都是求最大点权独立集。

    不难看出来,这题再多一个二分。

    注意的是在构造二部图的时候,按照c值的奇偶性构造。

    当c==1时要单独处理,因为如果有多个c==1的卡片,我们肯定会选当中p值最大的卡片。

      1 #include<bits/stdc++.h>
      2 #define F(i,a,b) for(int i=a;i<=b;i++)
      3 #define ___ freopen("in.txt","r",stdin);
      4 using namespace std;
      5 typedef long long ll;
      6 
      7 namespace Euler{
      8     const int N=2e5+7;
      9     int primes[N],tot=0;
     10     bool vis[N];
     11     void euler(){
     12         memset(vis,0,sizeof(vis));
     13         F(i,2,N){
     14             if(!vis[i])primes[++tot]=i;
     15             F(j,1,tot){
     16                 if(i*primes[j]>N)break;
     17                 vis[i*primes[j]]=1;
     18                 if(i%primes[j]==0)break;
     19             }
     20         }
     21     }
     22 }
     23 
     24 namespace ISAP{
     25     const int N=120,inf=~0U>>2,M=20000;
     26     struct edge{int t,f;edge*nxt,*pair;}*g[N],*d[N],pool[M],*cur=pool;
     27     int i,S,T,h[N],gap[N],maxflow;
     28     void init(int ss,int tt){for(S=ss,T=tt,cur=pool,i=1;i<=T;i++)g[i]=d[i]=NULL,h[i]=gap[i]=0;}
     29     void add(int s,int t,int f){
     30        // printf("s=%d,t=%d,f=%d
    ",s,t,f);
     31         edge*p=cur++;p->t=t,p->f=f,p->nxt=g[s],g[s]=p;
     32         p=cur++,p->t=s,p->f=0,p->nxt=g[t],g[t]=p;
     33         g[s]->pair=g[t],g[t]->pair=g[s];
     34     }
     35     int sap(int v,int flow){
     36         if(v==T)return flow;
     37         int rec=0;
     38         for(edge*p=d[v];p;p=p->nxt)if(h[v]==h[p->t]+1&&p->f){
     39             int ret=sap(p->t,min(flow-rec,p->f));
     40             p->f-=ret;p->pair->f+=ret;d[v]=p;
     41             if((rec+=ret)==flow)return flow;
     42         }
     43         if(!(--gap[h[v]]))h[S]=T;
     44         gap[++h[v]]++;d[v]=g[v];
     45         return rec;
     46     }
     47     int get_ans(){
     48         for(gap[maxflow=0]=T,i=1;i<=T;i++)d[i]=g[i];
     49         while(h[S]<T)maxflow+=sap(S,inf);
     50         return maxflow;
     51     }
     52 }
     53 
     54 int n,k;
     55 struct node
     56 {
     57     int p,c,l;
     58     node(int a=0,int b=0,int _c=0):p(a),c(b),l(_c){}
     59 }a[200],tmp[200];
     60 
     61 bool Find(int x)
     62 {
     63     using namespace Euler;
     64     int now=lower_bound(primes+1,primes+1+tot,x)-primes;
     65     if(now<=tot&&x==primes[now])return 1;
     66     return 0;
     67 }
     68 
     69 int check(int mid)
     70 {
     71     using namespace ISAP;
     72     int ed=0,sum=0,mxp=0,mxidx=-1;
     73     F(i,1,n)if(a[i].l<=mid)
     74     {
     75         if(a[i].c==1){if(a[i].p>mxp)mxp=a[i].p,mxidx=i;}
     76         else tmp[++ed]=a[i],sum+=a[i].p;
     77     }
     78     if(mxidx!=-1)tmp[++ed]=a[mxidx],sum+=a[mxidx].p;
     79     init(ed+1,ed+2);
     80     F(i,1,ed)if(tmp[i].c&1)add(S,i,tmp[i].p);else add(i,T,tmp[i].p);
     81     F(i,1,ed)if(tmp[i].c&1)
     82     {
     83         F(j,1,ed)if(tmp[j].c%2==0&&Find(tmp[i].c+tmp[j].c))add(i,j,inf);
     84     }
     85     return sum-get_ans()>=k;
     86 }
     87 
     88 int main()
     89 {
     90     Euler::euler();
     91     scanf("%d%d",&n,&k);
     92     F(i,1,n)scanf("%d%d%d",&a[i].p,&a[i].c,&a[i].l);
     93     int l=1,r=n,mid,ans=-1;
     94     while(l<=r)
     95     {
     96         mid=l+r>>1;
     97         if(check(mid))r=mid-1,ans=mid;
     98         else l=mid+1;
     99     }
    100     printf("%d
    ",ans);
    101     return 0;
    102 }
    View Code
  • 相关阅读:
    video标签
    正则表达式
    BOM和DOM
    css样式属性
    js简介
    格式与布局
    CSS样式表
    表单
    redis学习心得之三-【java操作redis】
    redis学习心得之二【redis主从配置】
  • 原文地址:https://www.cnblogs.com/bin-gege/p/6916070.html
Copyright © 2011-2022 走看看